Webpack:如何将非模块脚本及Polyfill加载至window全局作用域
解决Webpack Vendor Bundle全局函数无法访问的问题
我之前也碰到过一模一样的问题!Webpack默认会把所有模块包裹在它自己的模块系统(比如webpackJsonP)里,导致原本挂载在window上的第三方函数被封装起来,没法直接全局访问。而且ProvidePlugin确实不是干这个活的,先给你拆解原因,再给几个可行的解决方案:
一、为什么ProvidePlugin没用?
ProvidePlugin的作用是在模块代码中自动注入依赖,比如当你在代码里用$时,它会自动帮你引入jQuery,但它并不会把变量挂载到window全局作用域上——它只是让模块内部能直接用这个变量,和你要的“全局可访问”完全是两码事,所以没效果很正常。
二、解决方案:让Vendor文件在全局作用域执行
1. 用script-loader直接执行第三方文件
这个是最直接的方式,script-loader会跳过Webpack的模块封装,把文件内容直接在全局作用域(window)下执行,原来的全局函数自然就挂载到window上了。
- 先安装依赖:
npm install script-loader --save-dev - 在Webpack的
entry里配置Vendor bundle时,用script-loader!前缀引入需要全局执行的文件,同时把Polyfill也加进去:module.exports = { entry: { vendor: [ // 用script-loader执行第三方全局文件 'script-loader!./src/vendor/global-func-1.js', 'script-loader!./src/vendor/global-func-2.js', // 加入需要的Polyfill,比如core-js和regenerator-runtime 'core-js/stable', 'regenerator-runtime/runtime' ] }, // 其他配置... }
2. 用expose-loader精准暴露特定变量
如果你的第三方文件是模块化的,但你需要把其中某个变量暴露到window,可以用expose-loader:
- 安装依赖:
npm install expose-loader --save-dev - 在Webpack的
module.rules里配置:
这种方式适合需要精准控制暴露变量的场景,多个变量可以用数组或者链式配置。module.exports = { module: { rules: [ { // 匹配你的第三方文件 test: require.resolve('./src/vendor/some-module.js'), // 把模块里的`myGlobalFunc`变量暴露到window上 use: [{ loader: 'expose-loader', options: 'myGlobalFunc' }] } ] }, // 配合splitChunks把这些模块分到Vendor bundle optimization: { splitChunks: { cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]|src[\\/]vendor[\\/]/, name: 'vendor', chunks: 'all' } } } } }
3. 确保SplitChunks正确分离Vendor Bundle
不管用哪种loader,都要保证Webpack把第三方依赖和Polyfill正确打包到Vendor bundle里,上面的optimization.splitChunks配置已经包含了这部分——它会把node_modules和自定义vendor目录下的文件都分到vendor bundle里。
三、验证效果
构建完成后,在浏览器里打开页面,打开控制台直接输入你的全局函数名,比如myGlobalFunc(),如果能正常执行,就说明配置生效了!
内容的提问来源于stack exchange,提问作者Mick Feller
相关产品推荐
相关产品推荐

