webpackDemo讀書筆記

跬步千里發表於2018-07-30

零: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
				}
			}
		}
	}
};


複製程式碼