如何解决如何使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软件包有关?
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 举报,一经查实,本站将立刻删除。