微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使Webpack导入仅针对特定内部版本的polyfill?

如何解决如何使Webpack导入仅针对特定内部版本的polyfill?

我刚刚设法使webpack创建两个单独的构建,一个用于es5,另一个用于es6。 参见下面的配置文件

const path = require("path");

const common = require("./webpack.common");
const merge = require("webpack-merge");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
var HtmlWebpackPlugin = require("html-webpack-plugin");

const es5Config = merge(common,{
  mode: "production",output: {
    filename: "[name].[contentHash].bundle.es5.js",path: path.resolve(__dirname,"dist")
  },optimization: {
    minimizer: [
      new OptimizeCssAssetsPlugin(),new TerserPlugin(),new HtmlWebpackPlugin({
        template: "./src/template.html",minify: {
          removeAttributeQuotes: true,collapseWhitespace: true,removeComments: true
        }
      }),]
  },plugins: [

    new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),new CleanWebpackPlugin(),],module: {
    rules: [
      {
        test: /\.scss$/,use: [
          MiniCssExtractPlugin.loader,//3. Extract css into files
          "css-loader",//2. Turns css into commonjs
          "sass-loader" //1. Turns sass into css
        ]
      },{
      test: /\.m?js$/,exclude: /node_modules/,use: {
        loader: 'babel-loader',options: {
          presets: [
            ['@babel/preset-env',{
              modules: false,useBuiltIns: 'entry',targets: {
                browsers: [
                  "IE 11"
                ],},}],});

const es6Config = merge(common,output: {
    filename: "[name].[contentHash].bundle.es6.js",useBuiltIns: "usage",targets: {
                browsers: [
                  'Chrome >= 60','Safari >= 10.1','iOS >= 10.3','Firefox >= 54','Edge >= 15',});

module.exports = [es5Config,es6Config];

现在的问题是,我希望webpack仅导入es5构建的polyfill。并使用设置为use的usebuilins不能填充任何内容

我可能用错了吗,也许与node_modules软件包有关?

所以我只是将polyfill导入到主文件中,例如:

import "core-js/stable";
import "regenerator-runtime/runtime";

如何使这些导入仅针对es5构建添加?或如何从webpack包括polyfills / imports?

还有一个额外的问题,如果有人知道,我如何正确地将usebuiltins与“用法”一起使用?原因到目前为止,甚至以为polifylls是为我的主文件添加的,例如,我仍然在IE11中仍然遇到符号错误

解决方法

我知道了。这是webpack配置: 常见的:

const path = require("path");

module.exports = {
  entry: {
    main: "./src/index.js",vendor: "./src/vendor.js"
  },module: {
    rules: [
      {
        test: /\.html$/,use: ["html-loader"]
      },{
        test: /\.(svg|png|jpg|gif)$/,use: {
          loader: "file-loader",options: {
            name: "[name].[hash].[ext]",outputPath: "imgs"
          }
        }
      }
    ]
  }
};

产品:

const path = require("path");

const common = require("./webpack.common");
const merge = require("webpack-merge");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
var HtmlWebpackPlugin = require("html-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");

const es5Config = merge(common,{
  mode: "production",output: {
    filename: "[name].[contentHash].bundle.es5.js",path: path.resolve(__dirname,"dist")
  },optimization: {
    runtimeChunk: 'single',splitChunks: {
      chunks: 'all',maxInitialRequests: Infinity,minSize: 0,cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,name: (module) => {
            // get the name. E.g. node_modules/packageName/not/this/part.js
            // or node_modules/packageName
            const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
            // npm package names are URL-safe,but some servers don't like @ symbols
            return `npm.${packageName.replace('@','')}`;
          },},minimizer: [
      new OptimizeCssAssetsPlugin(),new TerserPlugin(),new HtmlWebpackPlugin({
        filename: 'main.aspx',template: "./src/main.html",// minify: {
        //   removeAttributeQuotes: true,//   collapseWhitespace: true,//   removeComments: true
        // }
      }),]
  },plugins: [
    new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),new CleanWebpackPlugin(),new BundleAnalyzerPlugin(),],module: {
    rules: [
      {
        test: /\.scss$/,use: [
          MiniCssExtractPlugin.loader,//3. Extract css into files
          "css-loader",//2. Turns css into commonjs
          "sass-loader" //1. Turns sass into css
        ]
      },{
      test: /\.m?js$/,exclude: /node_modules/,//exclude: /node_modules\/(?!(\@pnp)\/).*/,use: {
        loader: 'babel-loader',options: {
          //configFile : './es5.babel.config.json',presets: [
            ['@babel/preset-env',{
              modules: false,useBuiltIns: false,targets: {
                browsers: [
                  "IE 11"
                ],}],});

const es6Config = merge(common,output: {
    filename: "[name].[contentHash].bundle.es6.js",new HtmlWebpackPlugin({
        filename: 'main_es6.html',plugins: [

    new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),});
module.exports = [ es5Config,es6Config];

babel.config.json:

{
  "plugins": [
    [
      "@babel/plugin-transform-runtime",{
        "absoluteRuntime": true,"helpers": true,"regenerator": true,"useESModules": false
      }
    ]
  ]
}

因此,此结合cdn polyfill可以仅加载IE11的polifyll。它也有自己的构建。

这里唯一的问题是结果输出将具有单独的文件,并且es5构建在其所有脚本中都应该没有模块。同样对于es6,所有人都应该有模块。 然后,我必须去手动添加那些可以轻松创建自定义模板来处理的模板。

但是随后删除了polyfill的脚本,我仍然必须手动合并html文件。有人知道如何处理吗?

编辑: 1-对于属性,可以使用HtmlWebpackPlugin钩子()或ScriptExtHtmlWebpackPlugin将属性放置在标记中。

在此处找到带有钩子的代码:

const HtmlWebpackPlugin = require('html-webpack-plugin');


class es5TagTransformerHook {
  apply (compiler) {
    compiler.hooks.compilation.tap('MyPlugin',(compilation) => {
  
      HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapAsync(
        'es5TagTransformerHook',stacktraces
        async (data,cb) => {
          // Manipulate the content
          // data.html += 'The Magic Footer'
          // Tell webpack to move on
          data.bodyTags.forEach(t=>t.tagName === 'script'?t.attributes.nomodule = true:null)

          cb(null,data)
        }
      )
      
    })
  }
}

module.exports = es5TagTransformerHook

2-为了合并生成的html,我最终使用了这个要点: https://gist.github.com/agoldis/21782f3b9395f78d28dce23e3b6ddd56

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。