如何为EJS页面引入外部JavaScript脚本文件
问题:将EJS内嵌JS迁移到外部脚本文件并正确配置Express静态资源
背景
我是Node.js和Express的初学者,正在开发小型多页Web应用学习。目前能在各EJS页面用<script>标签编写JS,但想把所有JS代码统一放到单个外部脚本文件里,避免分散在多个页面。
项目结构
Project/ |-- app/ | |-- script.js | |-- public/ | |-- css/ | |-- style.css | |-- views/ | |-- home.ejs | |-- app.js |-- package.json |-- package-lock.json
尝试过的无效方法
- 方法1:将JS文件放在app文件夹并配置静态资源,仅CSS生效
const app = express(); app.use(express.static(__dirname + "/public")); app.use(express.static(__dirname + "/app")); - 方法2:使用path.join配置,无法同时适配CSS和JS
该方法来自旧Stack Overflow回答,不确定是否因版本问题失效。app.use('/app',express.static(path.join('../app'))); app.use('/public',express.static(path.join('../public')));
现有代码片段
EJS(home.ejs)
<div class="quiz-start" data-quiz='<%= JSON.stringify(savedQuiz) %>'> <h1 class="question-display"> <%= savedQuiz[currentQuizIndex].question %> </h1> <h1 class="answer-display hidden"> <%= savedQuiz[currentQuizIndex].answer %> </h1> <button class="next-btn hidden" onclick="nextQuiz()">Next</button> <button class="show-btn" onclick="showAns()">Answer</button> </div>
待迁移的内嵌JS代码
let answerShow = document.querySelector(".answer-display") let nextBtn = document.querySelector(".next-btn") let showBtn = document.querySelector(".show-btn") let currentIndex = <%= currentQuizIndex %>; const savedQuiz = JSON.parse(document.querySelector('.quiz-start').dataset.quiz); function nextQuiz() { currentIndex++; nextBtn.classList.add("hidden") answerShow.classList.add("hidden") showBtn.classList.remove("hidden") if (currentIndex >= savedQuiz.length) { currentIndex = 0; } document.querySelector('.question-display').textContent = savedQuiz[currentIndex].question; document.querySelector('.answer-display').textContent = savedQuiz[currentIndex].answer; } function showAns() { answerShow.classList.remove("hidden") nextBtn.classList.remove("hidden") showBtn.classList.add("hidden") }
解决方案
1. 修正Express静态资源配置
先确保引入path模块,再用path.join结合__dirname配置静态目录,避免相对路径错误:
const path = require('path'); const app = express(); // 配置public目录为静态资源,访问路径示例:/css/style.css app.use(express.static(path.join(__dirname, 'public'))); // 配置app目录为静态资源,访问路径示例:/script.js app.use(express.static(path.join(__dirname, 'app')));
如果需要给脚本目录加虚拟前缀,可改为:
app.use('/assets', express.static(path.join(__dirname, 'app')));
此时脚本访问路径变为/assets/script.js。
2. 处理外部脚本中的EJS变量
外部JS无法直接解析EJS语法,需通过页面全局变量传递currentIndex:
- 在EJS页面中先定义全局变量,再引入外部脚本:
<script> // 将EJS变量暴露给全局作用域 window.currentQuizIndex = <%= currentQuizIndex %>; </script> <script src="/script.js"></script> <!-- 若用虚拟前缀则改为/src/script.js -->
- 修改外部
script.js,使用全局变量替代EJS语法:
let answerShow = document.querySelector(".answer-display") let nextBtn = document.querySelector(".next-btn") let showBtn = document.querySelector(".show-btn") // 从全局获取currentIndex let currentIndex = window.currentQuizIndex; const savedQuiz = JSON.parse(document.querySelector('.quiz-start').dataset.quiz); function nextQuiz() { currentIndex++; nextBtn.classList.add("hidden") answerShow.classList.add("hidden") showBtn.classList.remove("hidden") if (currentIndex >= savedQuiz.length) { currentIndex = 0; } document.querySelector('.question-display').textContent = savedQuiz[currentIndex].question; document.querySelector('.answer-display').textContent = savedQuiz[currentIndex].answer; } function showAns() { answerShow.classList.remove("hidden") nextBtn.classList.remove("hidden") showBtn.classList.add("hidden") }
3. 验证配置是否生效
启动服务后,在浏览器直接访问脚本路径(如http://localhost:3000/script.js),若能看到脚本内容,说明静态资源配置成功。
内容的提问来源于stack exchange,提问作者TeDi
相关产品推荐
相关产品推荐

