零:AggressiveSplittingPlugin,
AggressiveSplittingPlugin 可以将 bundle 拆分成更小的 chunk,直到各个 chunk 的大小达到 option 设置的 maxSize。它通过目录结构将模块组织在一起。
用于将捆绑包拆分为多个较小的块以改进缓存。这对HTTP2 Web服务器最有效,否则会增加请求数量的开销
new webpack.optimize.AggressiveSplittingPlugin({
minSize: 30000,
maxSize: 50000
}),
一: 不见了
二:使用chunkhash!
hash:
任何一个改动都会影响另外其他的最终文件名。上线后,另外其他文件的浏览器缓存也全部失效。
那么如何避免这个问题呢?
答案就是chunkhash!
根据chunkhash的定义知道,chunkhash是根据具体模块文件的内容计算所得的hash值,
所以某个文件的改动只会影响它本身的hash指纹,不会影响其他文件
三: css 代码分离
extract-text-webpack-plugin
四: Code Splitting(代码分离)和Loaders(解析器)
example.js
require("bundle-loader!./file.js")(function(fileJsExports) {
console.log(fileJsExports);
});
file.js
module.exports = "It works";
五:代码分离和 异步import
通过异步import创建异步上下文,创建后,webpack会将 “1”,”2”分别单独打包出来
function loadC(name) {
return import("c/" + name);
}
Promise.all([loadC("1"), loadC("2")]).then(function(arr) {
console.log("c/1 and c/2 loaded", arr);
});
六:利用import()
语法创建ContextModule,它们被分成单独的块,如:./ templates
文件夹中的每个模块。
async function getTemplate(templateName) {
try {
let template = await import(`./templates/${templateName}`);
console.log(template);
} catch(err) {
console.error("template error");
return new Error(err);
}
}
getTemplate("foo");
getTemplate("bar");
getTemplate("baz");
七:如何过滤import()
语句的ContextModule结果。
如:在templates
文件夹中。 只有.js
文件会被单独打包, .noimport.js
文件不会被单独打包
async function getTemplate(templateName) {
try {
let template = await import(
/* webpackInclude: /\.js$/ */
/* webpackExclude: /\.noimport\.js$/ */
`./templates/${templateName}`
);
console.log(template);
} catch(err) {
console.error(err);
return new Error(err);
}
}
getTemplate("foo");
getTemplate("bar");
getTemplate("baz");
getTemplate("foo.noimport");
getTemplate("bar.noimport");
getTemplate("baz.noimport");
八: 给import异步导入的模块自定义名称
方式一:
import("./templates/foo" /* webpackChunkName: "chunk-foo" */ ).then(function(foo) {
console.log('foo:', foo);
})
方式二:
require.ensure([], function(require) {
var foo = require("./templates/foo");
console.log('foo:', foo);
}, "chunk-foo1");
方式三:
var createContextVar = "r";
import("./templates/ba" + createContextVar /* webpackChunkName: "chunk-bar-baz" */ ).then(function(bar) {
console.log('bar:', bar);
})
九:将第三方库代码与公共代码分别打包
使用optimization.splitChunks
进行自动重复数据删除
optimization: {
splitChunks: {
cacheGroups: {
commons: {
chunks: "initial",
minChunks: 2,
maxInitialRequests: 5, // The default limit is too small to showcase the effect
minSize: 0 // This is example is too small to create commons chunks
},
vendor: {
test: /node_modules/,
chunks: "initial",
name: "vendor",
priority: 10,
enforce: true
}
}
}
},
十:如何将入口点的深层祖先的常见模块拆分为单独的公共块
同九
十一: 创建DLL 或创建library
我觉得这种情况适用于单独编写的工具或组件库
十二: externals的使用
十三: 国际化(i18n)
example.js
console.log(__("Hello World"));
console.log(__("Missing Text"));
webpack.config.js
var path = require("path");
var I18nPlugin = require("i18n-webpack-plugin");
var languages = {
en: null,
de: require("./de.json")
};
module.exports = Object.keys(languages).map(function(language) {
return {
name: language,
// mode: "development || "production",
entry: "./example",
output: {
path: path.join(__dirname, "dist"),
filename: language + ".output.js"
},
plugins: [new I18nPlugin(languages[language])]
};
});
de.json
{
"Hello World": "Hallo Welt"
}
十四: tree shaking (通过side-effects属性删除无用代码)
example.js
import { a as a1, b as b1 } from "big-module";
import { a as a2, b as b2 } from "big-module-with-flag";
console.log(
a1,
b1,
a2,
b2
);
node_modules/big-module/package.json
{
"name": "big-module"
}
node_modules/big-module-with-flag/package.json
{
"name": "big-module-with-flag",
"sideEffects": false
}
node_modules/big-module(-with-flag)/index.js
export { a } from "./a";
export { b } from "./b";
export { c } from "./c";
十五: 通过webpack配置 指定特定的模块单独打包
var path = require("path");
module.exports = {
// mode: "development || "production",
entry: {
vendor1: ["./vendor1"],
vendor2: ["./vendor2"],
pageA: "./pageA",
pageB: "./pageB",
pageC: "./pageC"
},
output: {
path: path.join(__dirname, "dist"),
filename: "[name].js"
},
optimization: {
splitChunks: {
cacheGroups: {
vendor1: {
name: "vendor1",
test: "vendor1",
enforce: true
},
vendor2: {
name: "vendor2",
test: "vendor2",
enforce: true
}
}
}
}
};