Webpack未打包所有TypeScript文件的技术咨询
看起来你碰到了Webpack在多页面应用场景下的典型问题——Webpack是基于依赖图机制工作的:它从你配置的入口文件出发,只会打包那些被入口文件直接/间接引用的模块。你的login.ts从来没被main.ts或者任何被main.ts依赖的文件导入过,所以Webpack完全不知道它的存在,自然不会把formSubmitting函数打包进bundle里。
接下来我会针对你的场景给出几种实用的解决方案,同时解答你关于入口配置的疑问:
一、先明确你的核心疑问
1. 为什么formSubmitting没被打包?
如刚才所说,Webpack不会主动扫描你的所有TS文件,它只处理入口文件能“触及”到的模块。login.ts和main.ts完全是两个独立的文件,没有任何引用关联,所以被Webpack忽略了。
2. 你对entry: './javascript/main.ts'的使用对吗?
如果是单页面应用,这个配置是没问题的,但你的场景是多页面.NET Web应用,每个页面有自己的专属逻辑,同时有共享代码,单入口配置就不适用了:要么会漏打包页面专属代码,要么为了把所有代码塞进去导致bundle体积过大,影响页面加载速度。
二、针对你的场景的解决方案
方案1:配置多入口(推荐,适合多页面应用)
这个方案会给每个页面单独配置入口,生成对应的页面专属bundle,同时提取共享代码到公共bundle,兼顾打包完整性和加载性能。
步骤1:修改webpack.config.js
const path = require('path'); module.exports = { entry: { // 共享代码入口 main: './javascript/main.ts', // 每个页面的专属入口 login: './javascript/pages/login.ts' }, module: { rules: [ { test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/, }, ], }, resolve: { extensions: ['.tsx', '.ts', '.js'], }, output: { // 用[name]动态生成每个入口对应的bundle文件名 filename: '[name].bundle.js', path: path.resolve(__dirname, 'wwwroot/js/compiled'), // 每次打包前清空输出目录 clean: true }, devtool: 'inline-source-map', // 提取共享代码到公共bundle optimization: { splitChunks: { chunks: 'all', name: 'common' } } };
步骤2:修改CSHTML页面的脚本引用
每个页面只需要加载自己的专属bundle和公共bundle:
index.cshtml:
<html> <body> <input type="button" value="Go to Login Page" onclick="launchLogin();" /> <script src="~/js/compiled/common.bundle.js"></script> <script src="~/js/compiled/main.bundle.js"></script> </body> </html>
login.cshtml:
<html> <body> <form method="post" onsubmit="formSubmitting();"> <input type="submit" value="Login" /> </form> <script src="~/js/compiled/common.bundle.js"></script> <script src="~/js/compiled/login.bundle.js"></script> </body> </html>
方案2:在入口文件中显式导入所有页面模块(适合小型项目)
如果你的项目很小,不想配置多入口,可以在main.ts中显式导入所有页面的TS文件——哪怕只是导入不使用,Webpack也会把它们打包进去:
修改javascript/main.ts:
export function launchLogin(): void { window.location.href = '/login'; } // 显式导入login.ts,让Webpack感知到这个模块 import './pages/login.ts';
同时,你需要把login.ts中的函数挂载到全局window对象上,否则页面无法直接通过formSubmitting()调用(因为Webpack会把模块封装在闭包里):
修改javascript/pages/login.ts:
export function formSubmitting(): void { alert('Success!!!'); } // 挂载到全局window,让页面可以直接调用 (window as any).formSubmitting = formSubmitting;
这种方式的缺点是:所有页面的代码都会打包进同一个bundle,体积会随着页面增多而越来越大,影响页面加载速度。
三、额外建议
- 尽量避免在HTML中直接用
onclick/onsubmit这种内联事件绑定,推荐在TS文件中通过DOM选择器绑定事件,这样Webpack的tree-shaking可以更好地工作,同时代码更易维护。 - 对于多页面应用,方案1的多入口配置是长期来看更合理的选择,它能让每个页面只加载自己需要的代码,提升用户体验。
内容来源于stack exchange

