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

Webpack docs

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 阅读。