我用 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
。
留言板
歡迎留下建議與分享!希望一起交流!感恩!