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

Webpack打包报错:openTab未定义问题排查求助

问题:Webpack打包后控制台报错"openTab is not defined"

使用Webpack构建项目,入口为src/index.js,输出到dist/main.js,项目结构如下:

|- package.json
|- package-lock.json
|- webpack.config.js
|- /dist
  |- main.js
  |- index.html
|- /src
  |- index.js
  |- style.css
|- /node_modules

已完成npm init并安装相关依赖,打包运行后控制台提示"openTab is not defined",相关配置与代码如下:

Webpack 配置

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
     {
       test: /\.(png|svg|jpg|jpeg|gif)$/i,
       type: 'asset/resource',
     },
     {
      test: /\.css$/,
      use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

Index.html 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Restaurant Page</title>
    <link rel="stylesheet" href="/src/style.css">
    <script src="/dist/main.js"></script>

</head>
<body>
    <button class="tablink" onclick="openTab(event, 'tab1')"> Home </button>
    <button class="tablink" onclick="openTab(event, 'tab2')"> Menu </button>
    <button class="tablink" onclick="openTab(event, 'tab3')"> Contact us</button>


    <div id="tab1" class="tabcontent">
        <div class="nest">
         <div id="about" >
            <h1>Manqal Dönər <br><i>6 il sizinlə</i></h1>
            <p>İşdən evə yorğun gedib yemək hazirlamaq yerinə, meyumuzdan sifariş edin və evinizdə dadli təamlardan dadaraq ailənizlə gözəl vaxt keçirin! 
                <br>Ünvan:
                <br> <br>📍Baku , Mərdəkan qəs. Makaron fabriki ilə üz-üzə. <br>
            <br> Əlaqə: <br><br>
                📱 0559734939
            <br> 📱 0709734939 
            </p>

            <h2>Work Hours</h2> 
                    Sunday: 8am - 8pm <br><br>

                    Monday: 6am - 6pm <br><br>

                    Tuesday: 6am - 6pm <br><br>

                    Wednesday: 6am - 6pm <br><br>

                    Thursday: 6am - 10pm <br><br>

                    Friday: 6am - 10pm <br><br>

                    Saturday: 8am - 10pm <br><br>
            
        </div>
      </div>
    </div>
    <div id="tab2" class="tabcontent">
        <div class="nest-2">
        <h1>Menu</h1>
        <h2>Drinks</h2>
        <h3>Balli Chai</h3>
        <p>A Warm, sweet tea made with the highest quality honey and a bit of lemon to start your day off right!</p>
        <h3>Albali Chai</h3>
        <p>A comforting, almost filling, tea that is infused with the flavors of several kinds of berries. Best served cold, but can be served hot on request.</p>
        <h2> Chef Special </h2>
        <h3> Doner in Mangal </h3>
        <p>Doner made with love and the greasy and tasteful hands of Chef Seyran</p>
    </div>  
    </div>
   
    <div id="tab3" class="tabcontent">
        <h1>Managers</h1>
        <h3>Chief Manager</h3>
        <p>Arif Rzayev <br><br>011-111-11-11</p>
        <h3>Middle Manager</h3>
        <p>Orxan Mahmudov <br><br>011-222-22-22</p>
        <h3>Front-line Manager</h3>
        <p>Akif Quliyev <br><br>011-333-33-33</p>
    </div>
</body>
</html>

index.js 文件

import './style.css';

function openTab(event, tabName) {
    // Hide all tab contents
    const tabContents = document.querySelectorAll('.tabcontent');
    tabContents.forEach(content => {
        content.classList.remove('active');
    });

    // Show the selected tab content
    const selectedTab = document.getElementById(tabName);
    selectedTab.classList.add('active');
}

CSS 文件

/* Your CSS styles for tabs and content here */
.tabcontent {
    display: none;
}
.tabcontent.active {
    display: block;
}

报错原因

  1. Webpack模块作用域限制:Webpack默认将每个模块包裹在独立的函数作用域中,index.js内定义的openTab函数仅在模块内部可见,未暴露到全局window对象,HTML中的内联onclick无法找到该函数。
  2. CSS资源路径错误:HTML直接引用/src/style.css,但打包后src目录不会被复制到dist,生产环境下无法访问该文件(非当前报错直接原因,但需修复)。

解决方法

方法1:将函数挂载到全局作用域(快速临时方案)

修改src/index.js,把openTab挂载到window对象:

import './style.css';

function openTab(event, tabName) {
    const tabContents = document.querySelectorAll('.tabcontent');
    tabContents.forEach(content => {
        content.classList.remove('active');
    });
    const selectedTab = document.getElementById(tabName);
    selectedTab.classList.add('active');
}

// 暴露到全局
window.openTab = openTab;

方法2:使用事件监听替代内联onclick(推荐,符合模块化规范)

无需暴露全局函数,更贴合现代前端开发模式:

  1. 修改src/index.js,添加事件监听逻辑:
import './style.css';

function openTab(event, tabName) {
    const tabContents = document.querySelectorAll('.tabcontent');
    tabContents.forEach(content => {
        content.classList.remove('active');
    });
    const selectedTab = document.getElementById(tabName);
    selectedTab.classList.add('active');
}

// DOM加载完成后绑定事件
document.addEventListener('DOMContentLoaded', () => {
    const tabButtons = document.querySelectorAll('.tablink');
    tabButtons.forEach(button => {
        const tabName = button.dataset.tab;
        button.addEventListener('click', (e) => openTab(e, tabName));
    });
});
  1. 修改HTML中的按钮,移除内联onclick,添加data-tab属性:
<button class="tablink" data-tab="tab1"> Home </button>
<button class="tablink" data-tab="tab2"> Menu </button>
<button class="tablink" data-tab="tab3"> Contact us</button>

额外修复:CSS资源引用问题

删除HTML中的<link rel="stylesheet" href="/src/style.css">,因为style-loader已将CSS打包到main.js中,运行时会自动注入到页面的<style>标签,无需手动引用。


内容的提问来源于stack exchange,提问作者İlkin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 10:54:49