Webpack - 如何将非模块脚本加载到全局范围 | window
Webpack - How to load non module scripts into global scope | window
所以我有一些供应商文件需要 运行 从 window 作用域(它是一堆 window 作用域函数)加上我有一些我想要的 polyfill也捆绑到供应商捆绑包中。
所以我尝试了这样的事情:
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'js/vendor.min.js',
minChunks: Infinity,
})
entry: {
'vendor' : ['./vendor.js', './vendor2.js', './polyfills.js']
}
现在,当我 运行 我的 webpack 构建时,它确实生成了我的供应商包,但它全部包装在 webpackJsonP 包装器中,因此无法在 window 范围内访问这些功能。
我也考虑过使用 ProvidePlugin 之类的东西,但我根本无法使用它,因为我没有像 jQuery 这样的定义名称,其中所有内容都映射在下面。
在 webpack 中这甚至可能吗?
使用script-loader插件:
如果您希望整个脚本在全局命名空间中注册,您必须使用 script-loader。不推荐这样做,因为它破坏了模块的意义;-)
但是如果没有别的办法:
npm install --save-dev script-loader
This loader evaluates code in the global context, just like you would
add the code into a script tag. In this mode every normal library
should work. require, module, etc. are undefined.
Note: The file is added as string to the bundle. It is not minimized
by webpack, so use a minimized version. There is also no dev tool
support for libraries added by this loader.
然后在您的 entry.js 文件中您可以导入它 inline:
import "script-loader!./eluminate.js"
或通过配置:
module.exports = {
module: {
rules: [
{
test: /eluminate\.js$/,
use: [ 'script-loader' ]
}
]
}
}
在你的entry.js
import './eluminate.js';
正如我所说,它污染了全局命名空间:
script-loader should-not be used anymore. You can use raw-loader 改为:
npm install --save-dev raw-loader
并且:
import('!!raw-loader!./nonModuleScript.js').then(rawModule => eval.call(null, rawModule.default));
我在 raw-loader
之前使用 !!
因为我在文档中 in the case described:
Adding !!
to a request will disable all loaders specified in the configuration
当站点由于使用 unsafe eval expressions 而强制执行某些内容安全策略 (CSP) 规则时,上述两种解决方案都会出现问题,这绝对是一件好事。 (始终将安全视为网络中的第一个 class 公民;))
到目前为止我发现的替代解决方案是,假设您也在处理遗留代码库并且有这种需求
对于UMD
个模块,考虑import-loader,一个例子
test: require.resolve('jquery'),
use: {
loader: 'imports-loader',
options: {
wrapper: {
thisArg: 'window',
args: {
module: false,
exports: false,
define: false,
},
},
},
},
},
对于 CJS
模块导出到全局命名空间,考虑 expose-loader。
另外,如果你有时间,请 webpack shimming 阅读。
所以我有一些供应商文件需要 运行 从 window 作用域(它是一堆 window 作用域函数)加上我有一些我想要的 polyfill也捆绑到供应商捆绑包中。
所以我尝试了这样的事情:
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'js/vendor.min.js',
minChunks: Infinity,
})
entry: {
'vendor' : ['./vendor.js', './vendor2.js', './polyfills.js']
}
现在,当我 运行 我的 webpack 构建时,它确实生成了我的供应商包,但它全部包装在 webpackJsonP 包装器中,因此无法在 window 范围内访问这些功能。
我也考虑过使用 ProvidePlugin 之类的东西,但我根本无法使用它,因为我没有像 jQuery 这样的定义名称,其中所有内容都映射在下面。
在 webpack 中这甚至可能吗?
使用script-loader插件:
如果您希望整个脚本在全局命名空间中注册,您必须使用 script-loader。不推荐这样做,因为它破坏了模块的意义;-) 但是如果没有别的办法:
npm install --save-dev script-loader
This loader evaluates code in the global context, just like you would add the code into a script tag. In this mode every normal library should work. require, module, etc. are undefined.
Note: The file is added as string to the bundle. It is not minimized by webpack, so use a minimized version. There is also no dev tool support for libraries added by this loader.
然后在您的 entry.js 文件中您可以导入它 inline:
import "script-loader!./eluminate.js"
或通过配置:
module.exports = {
module: {
rules: [
{
test: /eluminate\.js$/,
use: [ 'script-loader' ]
}
]
}
}
在你的entry.js
import './eluminate.js';
正如我所说,它污染了全局命名空间:
script-loader should-not be used anymore. You can use raw-loader 改为:
npm install --save-dev raw-loader
并且:
import('!!raw-loader!./nonModuleScript.js').then(rawModule => eval.call(null, rawModule.default));
我在 raw-loader
之前使用 !!
因为我在文档中 in the case described:
Adding
!!
to a request will disable all loaders specified in the configuration
当站点由于使用 unsafe eval expressions 而强制执行某些内容安全策略 (CSP) 规则时,上述两种解决方案都会出现问题,这绝对是一件好事。 (始终将安全视为网络中的第一个 class 公民;))
到目前为止我发现的替代解决方案是,假设您也在处理遗留代码库并且有这种需求
对于UMD
个模块,考虑import-loader,一个例子
test: require.resolve('jquery'),
use: {
loader: 'imports-loader',
options: {
wrapper: {
thisArg: 'window',
args: {
module: false,
exports: false,
define: false,
},
},
},
},
},
对于 CJS
模块导出到全局命名空间,考虑 expose-loader。
另外,如果你有时间,请 webpack shimming 阅读。