我用 npx vite build 有問題 假設我在 main.js 的 var 參數命名為 aaa 但是我在django html中不能直接呼叫 aaa ?
你觀察得非常精準,這確實是 Vite 打包後 JavaScript 的行為特性,而不是 Django 的問題。以下是完整解釋與解法:
問題原因
當你在 main.js 中這樣寫:
var aaa = 123;
然後用 npx vite build 打包,它會做「作用域封裝」,例如:
(function() {
var aaa = 123;
})();
這樣 aaa 就是 區域變數,不會被暴露到 window 全域作用域,所以在 Django 的 HTML 中直接呼叫 aaa(例如在 <script> 或 console)會出現 Uncaught ReferenceError: aaa is not defined。
✅ 解決方法:將變數掛到 window
你可以這樣修改:
// 在 main.js window.aaa = 123;
或者更乾淨一點:
const aaa = 123; window.aaa = aaa;
這樣在 Django 的 HTML 或瀏覽器 console 裡就可以用:
<script> console.log(aaa); // 123 </script>
建議
為了避免污染全域命名空間,建議你可以封裝成物件,例如:
window.MyApp = {
aaa: 123,
setSomething: function () { ... },
init: function () { ... }
};
然後在 Django 中使用:
<script> MyApp.setSomething(); console.log(MyApp.aaa); </script>
補充:為什麼會有這種封裝?
因為 Vite 是基於 ESM 模組打包設計的,它會自動把模組變數包在閉包裡(避免命名衝突),這是現代工具(像 Vite、Webpack、Rollup)的常見行為。
如果你還想從 Django 傳資料進去 Vite 模組中,也可以用 window.some_data = {{ some_value|json_script:"data-id" }} + 在 main.js 中讀取,這我也可以幫你補上。需要嗎?
這個 window 是什麼意思?
很好問題!這是 JavaScript 的核心觀念之一。
window 是什麼?
在瀏覽器環境中,window 是 全域物件 (global object)。
也就是說:
-
所有在全域宣告的變數、函式、定時器、瀏覽器 API,都會掛在
window上。 -
它代表的是「整個瀏覽器的視窗」,同時也是全域的命名空間。
✅ 你可以這樣理解:
var aaa = 123; console.log(window.aaa); // ✅ 123
function hello() {
alert("Hi!");
}
console.log(window.hello); // ✅ function hello()
所以 window 是你放「全域資源」的地方。如果你想讓一個變數能在 HTML 中的 <script> 或其他 JS 模組裡被存取,那就要掛到 window 上。
但注意:用 var 和 let / const 有差!
var aaa = 123; console.log(window.aaa); // ✅ 123 let bbb = 456; console.log(window.bbb); // ❌ undefined
只有 var 聲明的變數會自動變成 window 的屬性,
let 和 const 則是屬於「區塊作用域」,不會掛在 window 上。
✅ 實用用途
-
從 Django template 傳值給 JavaScript
<script>
window.username = "{{ user.username }}";
</script>
然後在 Vite 的 main.js 中用:
console.log(window.username);
模組化開發時暴露某些功能
window.MyApp = {
sayHi: function() {
alert("Hi!");
}
};
然後你可以在 HTML 中:
<script> MyApp.sayHi(); </script>
延伸(Node.js 裡面是 global) 在 Node.js 裡沒有 window,取而代之的是 global:
global.xxx = 123;
但在瀏覽器就是 window。

留言板
歡迎留下建議與分享!希望一起交流!感恩!