You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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
    app.use('/app',express.static(path.join('../app')));
    app.use('/public',express.static(path.join('../public')));
    
    该方法来自旧Stack Overflow回答,不确定是否因版本问题失效。

现有代码片段

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:57:37