Webpack - 构建多个条目,但只包含一次 polyfills 和模块包装器

时间:2021-02-11 13:28:54

标签: javascript webpack

我有以下 webpack 配置,它遍历多个 PHP 包,在各自的 .js 目录中查找 .scss/resources 文件,构建它们并将它们放入 {{ 1}} 模块的目录。这允许我编写属于包的现代 ES6,而无需为其创建 webpack 配置。在监视模式下,如果我添加一个新文件就必须重新启动它,否则它运行良好。

/out/src

然而,有一些关于文件大小的警告:我必须使用 corejs 添加 polyfills,这样生成的代码才能在旧浏览器中工作,而且 webpack 似乎正在为每个文件添加必要的 polyfills,因此其中许多被多次包含。此外,webpack 将每个文件与其模块包装器代码捆绑在一起,以便它可以单独执行。

这里是我的问题:

  • 是否可以使用包含在所有页面中的 polyfill 构建一个 js 文件,以便它们不再包含在每个文件中,但还保留“使用”参数,以便仅使用的功能进行 polyfill?
  • 我能否让这个中心依赖也成为唯一一个包含 webpack 模块包装器代码以节省更多文件大小的依赖?其他 javascript 文件动态包含在 PHP 模板中(并且大多数脚本仅在少数页面上使用),因此构建包含所有内容的巨大分块包不是一个好的选择。

编辑: 尝试下面的答案后,条目如下所示:

const getEntries = () => {
  let js = glob.sync("./vendor/myvendor/**/resources/**/!(node_modules)/**/*.js");
  let css = glob.sync("./vendor/myvendor/**/resources/**/!(node_modules)/**/*.scss");
  if (js.length === 0 && css.length === 0) {
    return "./noop.js";
  }
  let entries = {};
  for (let i = 0; i < js.length; i++) {
    const p = js[i];
    const outPath = p.replace("/resources/", "/out/src/");
    entries[outPath] = p;
  }
  for (let i = 0; i < css.length; i++) {
    const p = css[i];
    const outPath = p.replace("/resources/", "/out/src/").replace(".scss", "");
    entries[outPath] = p;
  }
  return entries;
};

module.exports = {
  mode: "production",
  entry: getEntries(),
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          // Compiles Sass to CSS
          MiniCssExtractPlugin.loader,
          "css-loader",
          "sass-loader",
        ],
      },
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: [["@babel/preset-env", { debug: true, useBuiltIns: "usage", corejs: 3 }]],
            plugins: [["@babel/plugin-transform-runtime", { corejs: 3 }]],
          },
        },
      },
    ],
  },
  output: { path: __dirname, filename: "[name]" },
  plugins: [new MiniCssExtractPlugin()],
  watchOptions: {
    ignored: ["node_modules", "**/Tests/**"],
  },
};

(这是修改后的getEntries函数的返回值)

我添加了一个空的 { './vendor/myVendor/myModule0/out/src/js/countdown.js': { import: './vendor/myVendor/myModule0/resources/js/countdown.js', dependOn: 'polyfills.min.js' }, './vendor/myVendor/myModule0/out/src/js/paymentSelect.js': { import: './vendor/myVendor/myModule0/resources/js/paymentSelect.js', dependOn: 'polyfills.min.js' }, './vendor/myVendor/myModule0/out/src/js/shippingAddressSelect.js': { import: './vendor/myVendor/myModule0/resources/js/shippingAddressSelect.js', dependOn: 'polyfills.min.js' }, './vendor/myVendor/myModule0/out/src/js/modal.js': { import: './vendor/myVendor/myModule0/resources/js/modal.js', dependOn: 'polyfills.min.js' }, './vendor/myVendor/oxid-factfinder-extends/out/src/js/custom.js': { import: './vendor/myVendor/oxid-factfinder-extends/resources/js/custom.js', dependOn: 'polyfills.min.js' }, './vendor/myVendor/oxid-faq/out/src/js/faqForm.js': { import: './vendor/myVendor/oxid-faq/resources/js/faqForm.js', dependOn: 'polyfills.min.js' }, './vendor/myVendor/oxid-klarna-extends/out/src/js/payments_handler.js': { import: './vendor/myVendor/oxid-klarna-extends/resources/js/payments_handler.js', dependOn: 'polyfills.min.js' }, './vendor/myVendor/oxid-mobile-menu/out/src/js/filter-drawer.js': { import: './vendor/myVendor/oxid-mobile-menu/resources/js/filter-drawer.js', dependOn: 'polyfills.min.js' }, './vendor/myVendor/oxid-mobile-menu/out/src/js/mobile-menu.js': { import: './vendor/myVendor/oxid-mobile-menu/resources/js/mobile-menu.js', dependOn: 'polyfills.min.js' }, './vendor/myVendor/oxid-storefinder/out/src/js/store_request.js': { import: './vendor/myVendor/oxid-storefinder/resources/js/store_request.js', dependOn: 'polyfills.min.js' }, 'polyfills.min.js': './polyfills.js' } 并将其包含在各个 js 文件中,每个文件的顶部都带有 polyfills.js,但是 polyfills 文件的文件大小保持在 202 字节,并且各个模块没有得到较小。

1 个答案:

答案 0 :(得分:1)

您可以使用一个 polyfill 文件,以便与其他文件共享。

entry: {
    index: {
      import: './sources/js/index.js',
      dependOn: 'share'
    },
    about: {
      import: './sources/js/about.js',
      dependOn: 'share'
    },
    contact: {
      import: './sources/js/contact.js'
    },
    share: './sources/js/module/share.js'
  },

看看我的例子 webpack-boilerplate。当然,这个共享文件必须包含在每个要使用它的文件中。

另见文档 entry-context

--------更新--------

部分,这也是我的错,如果你要一个 webpack,请告诉我它是什么版本:)

  1. 尝试通过将 seBuiltIns: "usage" 更改为 useBuiltIns: "entry" 来减小大小
  2. 我看到您没有 optimization 部分:
optimization: {
  minimize: true,
  splitChunks: {
    cacheGroups: {
      commons: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendors',
        chunks: 'all',
      },
    },
  },
}

一开始就是这样。不幸的是,这是一个非常大的领域,无法用几句话来描述。最好的方法是去 github 分析 webpack-boilerplate 及其文档。这是很多小时的阅读和测试。

相关问题