webpack执行机制流程是怎么样的 webpack执行机制流程是怎么样的

webpack\u6267\u884c\u673a\u5236\u6d41\u7a0b\u662f\u600e\u4e48\u6837\u7684

Sims2PackInstaller_v1514.exe \u5982\u679c\u662f\u8fd9\u4e2a\u5c31\u662f\u7528\u6765\u5b89\u88c5Sims2Pack\u7684\u5de5\u5177\uff0c \u4e5f\u53ef\u4ee5\u7528\u6765\u6574\u7406\u5b89\u88c5\u540e\u7684\u4e1c\u897f\uff0c \u76f8\u5f53\u4e8e\u5b98\u65b9\u7684\u201c\u5185\u5bb9\u7ba1\u7406\u5668\u201d\uff0c

\u3000\u3000\u51e0\u4e4e\u6240\u6709\u4e1a\u52a1\u7684\u5f00\u53d1\u6784\u5efa\u90fd\u4f1a\u7528\u5230 webpack \u3002\u7684\u786e\uff0c\u4f5c\u4e3a\u6a21\u5757\u52a0\u8f7d\u548c\u6253\u5305\u795e\u5668\uff0c\u53ea\u9700\u914d\u7f6e\u51e0\u4e2a\u6587\u4ef6\uff0c\u52a0\u8f7d\u5404\u79cd loader \u5c31\u53ef\u4ee5\u4eab\u53d7\u65e0\u75db\u6d41\u7a0b\u5316\u5f00\u53d1\u3002\u4f46\u5bf9\u4e8e webpack \u8fd9\u6837\u4e00\u4e2a\u590d\u6742\u5ea6\u8f83\u9ad8\u7684\u63d2\u4ef6\u96c6\u5408\uff0c\u5b83\u7684\u6574\u4f53\u6d41\u7a0b\u53ca\u601d\u60f3\u5bf9\u6211\u4eec\u6765\u8bf4\u8fd8\u662f\u5f88\u900f\u660e\u7684\u3002\u90a3\u4e48\u63a5\u4e0b\u6765\u6211\u4f1a\u5e26\u4f60\u4e86\u89e3 webpack \u8fd9\u6837\u4e00\u4e2a\u6784\u5efa\u9ed1\u76d2\uff0c\u9996\u5148\u6765\u8c08\u8c08\u5b83\u7684\u6d41\u7a0b\u3002

\u3000\u3000\u51c6\u5907\u5de5\u4f5c

\u3000\u30001. webstorm \u4e2d\u914d\u7f6e webpack-webstorm-debugger-script

\u3000\u3000\u5728\u5f00\u59cb\u4e86\u89e3\u4e4b\u524d\uff0c\u5fc5\u987b\u8981\u80fd\u5bf9 webpack \u6574\u4e2a\u6d41\u7a0b\u8fdb\u884c debug \uff0c\u914d\u7f6e\u8fc7\u7a0b\u6bd4\u8f83\u7b80\u5355\u3002

\u3000\u3000\u5148\u5c06 webpack-webstorm-debugger-script \u4e2d\u7684\u8f6f\u4ef6\u5916\u5305\u4f01\u4e1a\u516c\u53f8http://www.yingtaow.com?webstorm-debugger.js \u7f6e\u4e8e webpack.config.js \u7684\u540c\u4e00\u76ee\u5f55\u4e0b\uff0c\u642d\u5efa\u597d\u4f60\u7684\u811a\u624b\u67b6\u540e\u5c31\u53ef\u4ee5\u76f4\u63a5 Debug \u8fd9\u4e2a webstorm-debugger.js \u6587\u4ef6\u4e86\u3002

\u3000\u30002. webpack.config.js \u914d\u7f6e

\u3000\u3000\u4f30\u8ba1\u5927\u5bb6\u5bf9 webpack.config.js \u7684\u914d\u7f6e\u4e5f\u5c1d\u8bd5\u8fc7\u4e0d\u5c11\u6b21\u4e86\uff0c\u8fd9\u91cc\u5c31\u5927\u81f4\u5bf9\u8fd9\u4e2a\u914d\u7f6e\u6587\u4ef6\u8fdb\u884c\u4e2a\u5206\u6790\u3002

\u3000\u3000var path = require('path');

\u3000\u3000var node_modules = path.resolve(__dirname, 'node_modules');

\u3000\u3000var pathToReact = path.resolve(node_modules, 'react/dist/react.min.js');

\u3000\u3000module.exports = {

\u3000\u3000// \u5165\u53e3\u6587\u4ef6\uff0c\u662f\u6a21\u5757\u6784\u5efa\u7684\u8d77\u70b9\uff0c\u540c\u65f6\u6bcf\u4e00\u4e2a\u5165\u53e3\u6587\u4ef6\u5bf9\u5e94\u6700\u540e\u751f\u6210\u7684\u4e00\u4e2a chunk\u3002

\u3000\u3000entry: {

\u3000\u3000bundle: [

\u3000\u3000'webpack/hot/dev-server',

\u3000\u3000'webpack-dev-server/client?http://localhost:8080',

\u3000\u3000path.resolve(__dirname, 'app/app.js')

\u3000\u3000],

\u3000\u3000},

\u3000\u3000// \u6587\u4ef6\u8def\u5f84\u6307\u5411(\u53ef\u52a0\u5feb\u6253\u5305\u8fc7\u7a0b)\u3002

\u3000\u3000resolve: {

\u3000\u3000alias: {

\u3000\u3000'react': pathToReact

\u3000\u3000}

\u3000\u3000},

\u3000\u3000// \u751f\u6210\u6587\u4ef6\uff0c\u662f\u6a21\u5757\u6784\u5efa\u7684\u7ec8\u70b9\uff0c\u5305\u62ec\u8f93\u51fa\u6587\u4ef6\u4e0e\u8f93\u51fa\u8def\u5f84\u3002

\u3000\u3000output: {

\u3000\u3000path: path.resolve(__dirname, 'build'),

\u3000\u3000filename: '[name].js',

\u3000\u3000},

\u3000\u3000// \u8fd9\u91cc\u914d\u7f6e\u4e86\u5904\u7406\u5404\u6a21\u5757\u7684 loader \uff0c\u5305\u62ec css \u9884\u5904\u7406 loader \uff0ces6 \u7f16\u8bd1 loader\uff0c\u56fe\u7247\u5904\u7406 loader\u3002

\u3000\u3000module: {

\u3000\u3000loaders: [

\u3000\u3000{

\u3000\u3000test: /\.js$/,

\u3000\u3000loader: 'babel',

\u3000\u3000query: {

\u3000\u3000presets: ['es2015', 'react']

\u3000\u3000}

\u3000\u3000}

\u3000\u3000],

\u3000\u3000noParse: [pathToReact]

\u3000\u3000},

\u3000\u3000// webpack \u5404\u63d2\u4ef6\u5bf9\u8c61\uff0c\u5728 webpack \u7684\u4e8b\u4ef6\u6d41\u4e2d\u6267\u884c\u5bf9\u5e94\u7684\u65b9\u6cd5\u3002

\u3000\u3000plugins: [

\u3000\u3000new webpack.HotModuleReplacementPlugin();

\u3000\u3000]

\u3000\u3000};

\u3000\u3000\u9664\u6b64\u4e4b\u5916\u518d\u5927\u81f4\u4ecb\u7ecd\u4e0b webpack \u7684\u4e00\u4e9b\u6838\u5fc3\u6982\u5ff5:

\u3000\u3000loader : \u80fd\u8f6c\u6362\u5404\u7c7b\u8d44\u6e90\uff0c\u5e76\u5904\u7406\u6210\u5bf9\u5e94\u6a21\u5757\u7684\u52a0\u8f7d\u5668\u3002loader \u95f4\u53ef\u4ee5\u4e32\u884c\u4f7f\u7528\u3002

\u3000\u3000chunk : code splitting\u540e\u7684\u4ea7\u7269\uff0c\u4e5f\u5c31\u662f\u6309\u9700\u52a0\u8f7d\u7684\u5206\u5757\uff0c\u88c5\u8f7d\u4e86\u4e0d\u540c\u7684module\u3002

\u3000\u3000\u5bf9\u4e8emodule\u548cchunk\u7684\u5173\u7cfb\u53ef\u4ee5\u53c2\u7167webpack\u5b98\u65b9\u7684\u8fd9\u5f20\u56fe:

\u3000\u3000plugin : webpack \u7684\u63d2\u4ef6\u5b9e\u4f53\uff0c\u8fd9\u91cc\u4ee5 UglifyJsPlugin \u4e3a\u4f8b\u3002

\u3000\u3000function UglifyJsPlugin(options) {

\u3000\u3000this.options = options;

\u3000\u3000}

\u3000\u3000module.exports = UglifyJsPlugin;

\u3000\u3000UglifyJsPlugin.prototype.apply = function(compiler) {

\u3000\u3000compiler.plugin("compilation", function(compilation) {

\u3000\u3000compilation.plugin("build-module", function(module) {

\u3000\u3000});

\u3000\u3000compilation.plugin("optimize-chunk-assets", function(chunks, callback) {

\u3000\u3000// Uglify \u903b\u8f91

\u3000\u3000});

\u3000\u3000compilation.plugin("normal-module-loader", function(context) {

\u3000\u3000});

\u3000\u3000});

\u3000\u3000};

\u3000\u3000\u5728 webpack \u4e2d\u4f60\u7ecf\u5e38\u53ef\u4ee5\u770b\u5230 compilation.plugin('xxx', callback) \uff0c\u4f60\u53ef\u4ee5\u628a\u5b83\u5f53\u4f5c\u662f\u4e00\u4e2a\u4e8b\u4ef6\u7684\u7ed1\u5b9a\uff0c\u8fd9\u4e9b\u4e8b\u4ef6\u5728\u6253\u5305\u65f6\u7531 webpack \u6765\u89e6\u53d1\u3002

\u3000\u30003. \u6d41\u7a0b\u603b\u89c8

\u3000\u3000\u5728\u5177\u4f53\u6d41\u7a0b\u5b66\u4e60\u524d\uff0c\u53ef\u4ee5\u5148\u901a\u8fc7\u8fd9\u5e45 webpack\u6574\u4f53\u6d41\u7a0b\u56fe \u4e86\u89e3\u4e00\u4e0b\u5927\u81f4\u6d41\u7a0b(\u5efa\u8bae\u4fdd\u5b58\u4e0b\u6765\u67e5\u770b)\u3002

\u3000\u3000shell \u4e0e config \u89e3\u6790

\u3000\u3000\u6bcf\u6b21\u5728\u547d\u4ee4\u884c\u8f93\u5165 webpack \u540e\uff0c\u64cd\u4f5c\u7cfb\u7edf\u90fd\u4f1a\u53bb\u8c03\u7528 ./node_modules/.bin/webpack \u8fd9\u4e2a shell \u811a\u672c\u3002\u8fd9\u4e2a\u811a\u672c\u4f1a\u53bb\u8c03\u7528./node_modules/webpack/bin/webpack.js \u5e76\u8ffd\u52a0\u8f93\u5165\u7684\u53c2\u6570\uff0c\u5982 -p , -w \u3002(\u56fe\u4e2d webpack.js \u662f webpack \u7684\u542f\u52a8\u6587\u4ef6\uff0c\u800c $@ \u662f\u540e\u7f00\u53c2\u6570)

\u3000\u3000\u5728 webpack.js \u8fd9\u4e2a\u6587\u4ef6\u4e2d webpack \u901a\u8fc7 optimist \u5c06\u7528\u6237\u914d\u7f6e\u7684 webpack.config.js \u548c shell \u811a\u672c\u4f20\u8fc7\u6765\u7684\u53c2\u6570\u6574\u5408\u6210 options \u5bf9\u8c61\u4f20\u5230\u4e86\u4e0b\u4e00\u4e2a\u6d41\u7a0b\u7684\u63a7\u5236\u5bf9\u8c61\u4e2d\u3002

\u3000\u30001. optimist

\u3000\u3000\u548c commander \u4e00\u6837\uff0coptimist \u5b9e\u73b0\u4e86 node \u547d\u4ee4\u884c\u7684\u89e3\u6790\uff0c\u5176 API \u8c03\u7528\u975e\u5e38\u65b9\u4fbf\u3002

\u3000\u3000var optimist = require("optimist");

\u3000\u3000optimist

\u3000\u3000.boolean("json").alias("json", "j").describe("json")

\u3000\u3000.boolean("colors").alias("colors", "c").describe("colors")

\u3000\u3000.boolean("watch").alias("watch", "w").describe("watch")

\u3000\u3000...

\u3000\u3000\u83b7\u53d6\u5230\u540e\u7f00\u53c2\u6570\u540e\uff0coptimist \u5206\u6790\u53c2\u6570\u5e76\u4ee5\u952e\u503c\u5bf9\u7684\u5f62\u5f0f\u628a\u53c2\u6570\u5bf9\u8c61\u4fdd\u5b58\u5728 optimist.argv \u4e2d\uff0c\u6765\u770b\u770b argv \u7a76\u7adf\u6709\u4ec0\u4e48\uff1f

\u3000\u3000// webpack --hot -w

\u3000\u3000{

\u3000\u3000hot: true,

\u3000\u3000profile: false,

\u3000\u3000watch: true,

\u3000\u3000...

\u3000\u3000}

\u3000\u30002. config \u5408\u5e76\u4e0e\u63d2\u4ef6\u52a0\u8f7d

\u3000\u3000\u5728\u52a0\u8f7d\u63d2\u4ef6\u4e4b\u524d\uff0cwebpack \u5c06 webpack.config.js \u4e2d\u7684\u5404\u4e2a\u914d\u7f6e\u9879\u62f7\u8d1d\u5230 options \u5bf9\u8c61\u4e2d\uff0c\u5e76\u52a0\u8f7d\u7528\u6237\u914d\u7f6e\u5728 webpack.config.js \u7684 plugins \u3002\u63a5\u7740 optimist.argv \u4f1a\u88ab\u4f20\u5165\u5230 ./node_modules/webpack/bin/convert-argv.js \u4e2d\uff0c\u901a\u8fc7\u5224\u65ad argv \u4e2d\u53c2\u6570\u7684\u503c\u51b3\u5b9a\u662f\u5426\u53bb\u52a0\u8f7d\u5bf9\u5e94\u63d2\u4ef6\u3002(\u81f3\u4e8e webpack \u63d2\u4ef6\u8fd0\u884c\u673a\u5236\uff0c\u5728\u4e4b\u540e\u7684\u8fd0\u884c\u673a\u5236\u7bc7\u4f1a\u63d0\u5230)

\u3000\u3000ifBooleanArg("hot", function() {

\u3000\u3000ensureArray(options, "plugins");

\u3000\u3000var HotModuleReplacementPlugin = require("../lib/HotModuleReplacementPlugin");

\u3000\u3000options.plugins.push(new HotModuleReplacementPlugin());

\u3000\u3000});

\u3000\u3000...

\u3000\u3000return options;

\u3000\u3000options \u4f5c\u4e3a\u6700\u540e\u8fd4\u56de\u7ed3\u679c\uff0c\u5305\u542b\u4e86\u4e4b\u540e\u6784\u5efa\u9636\u6bb5\u6240\u9700\u7684\u91cd\u8981\u4fe1\u606f\u3002

\u3000\u3000{

\u3000\u3000entry: {},//\u5165\u53e3\u914d\u7f6e

\u3000\u3000output: {}, //\u8f93\u51fa\u914d\u7f6e

\u3000\u3000plugins: [], //\u63d2\u4ef6\u96c6\u5408(\u914d\u7f6e\u6587\u4ef6 + shell\u6307\u4ee4)

\u3000\u3000module: { loaders: [ [Object] ] }, //\u6a21\u5757\u914d\u7f6e

\u3000\u3000context: //\u5de5\u7a0b\u8def\u5f84

\u3000\u3000...

\u3000\u3000}

\u3000\u3000\u8fd9\u548c webpack.config.js \u7684\u914d\u7f6e\u975e\u5e38\u76f8\u4f3c\uff0c\u53ea\u662f\u591a\u4e86\u4e00\u4e9b\u7ecf shell \u4f20\u5165\u7684\u63d2\u4ef6\u5bf9\u8c61\u3002\u63d2\u4ef6\u5bf9\u8c61\u4e00\u521d\u59cb\u5316\u5b8c\u6bd5\uff0c options \u4e5f\u5c31\u4f20\u5165\u5230\u4e86\u4e0b\u4e2a\u6d41\u7a0b\u4e2d\u3002

\u3000\u3000var webpack = require("../lib/webpack.js");

\u3000\u3000var compiler = webpack(options);

\u3000\u3000\u7f16\u8bd1\u4e0e\u6784\u5efa\u6d41\u7a0b

\u3000\u3000\u5728\u52a0\u8f7d\u914d\u7f6e\u6587\u4ef6\u548c shell \u540e\u7f00\u53c2\u6570\u7533\u660e\u7684\u63d2\u4ef6\uff0c\u5e76\u4f20\u5165\u6784\u5efa\u4fe1\u606f options \u5bf9\u8c61\u540e\uff0c\u5f00\u59cb\u6574\u4e2a webpack \u6253\u5305\u6700\u6f2b\u957f\u7684\u4e00\u6b65\u3002\u800c\u8fd9\u4e2a\u65f6\u5019\uff0c\u771f\u6b63\u7684 webpack \u5bf9\u8c61\u624d\u521a\u88ab\u521d\u59cb\u5316\uff0c\u5177\u4f53\u7684\u521d\u59cb\u5316\u903b\u8f91\u5728 lib/webpack.js \u4e2d\uff0c\u5982\u4e0b:

\u3000\u3000function webpack(options) {

\u3000\u3000var compiler = new Compiler();

\u3000\u3000...// \u68c0\u67e5options,\u82e5watch\u5b57\u6bb5\u4e3atrue,\u5219\u5f00\u542fwatch\u7ebf\u7a0b

\u3000\u3000return compiler;

\u3000\u3000}

\u3000\u3000...

\u3000\u3000webpack \u7684\u5b9e\u9645\u5165\u53e3\u662f Compiler \u4e2d\u7684 run \u65b9\u6cd5\uff0crun \u4e00\u65e6\u6267\u884c\u540e\uff0c\u5c31\u5f00\u59cb\u4e86\u7f16\u8bd1\u548c\u6784\u5efa\u6d41\u7a0b \uff0c\u5176\u4e2d\u6709\u51e0\u4e2a\u6bd4\u8f83\u5173\u952e\u7684 webpack \u4e8b\u4ef6\u8282\u70b9\u3002

\u3000\u3000compile \u5f00\u59cb\u7f16\u8bd1

\u3000\u3000make \u4ece\u5165\u53e3\u70b9\u5206\u6790\u6a21\u5757\u53ca\u5176\u4f9d\u8d56\u7684\u6a21\u5757\uff0c\u521b\u5efa\u8fd9\u4e9b\u6a21\u5757\u5bf9\u8c61

\u3000\u3000build-module \u6784\u5efa\u6a21\u5757

\u3000\u3000after-compile \u5b8c\u6210\u6784\u5efa

\u3000\u3000seal \u5c01\u88c5\u6784\u5efa\u7ed3\u679c

\u3000\u3000emit \u628a\u5404\u4e2achunk\u8f93\u51fa\u5230\u7ed3\u679c\u6587\u4ef6

\u3000\u3000after-emit \u5b8c\u6210\u8f93\u51fa

\u3000\u30001. \u6838\u5fc3\u5bf9\u8c61 Compilation

\u3000\u3000compiler.run \u540e\u9996\u5148\u4f1a\u89e6\u53d1 compile \uff0c\u8fd9\u4e00\u6b65\u4f1a\u6784\u5efa\u51fa Compilation \u5bf9\u8c61:

\u3000\u3000compilation\u7c7b\u56fe

\u3000\u3000\u8fd9\u4e2a\u5bf9\u8c61\u6709\u4e24\u4e2a\u4f5c\u7528\uff0c\u4e00\u662f\u8d1f\u8d23\u7ec4\u7ec7\u6574\u4e2a\u6253\u5305\u8fc7\u7a0b\uff0c\u5305\u542b\u4e86\u6bcf\u4e2a\u6784\u5efa\u73af\u8282\u53ca\u8f93\u51fa\u73af\u8282\u6240\u5bf9\u5e94\u7684\u65b9\u6cd5\uff0c\u53ef\u4ee5\u4ece\u56fe\u4e2d\u770b\u5230\u6bd4\u8f83\u5173\u952e\u7684\u6b65\u9aa4\uff0c\u5982 addEntry() , _addModuleChain() , buildModule() , seal() , createChunkAssets() (\u5728\u6bcf\u4e00\u4e2a\u8282\u70b9\u90fd\u4f1a\u89e6\u53d1 webpack \u4e8b\u4ef6\u53bb\u8c03\u7528\u5404\u63d2\u4ef6)\u3002\u4e8c\u662f\u8be5\u5bf9\u8c61\u5185\u90e8\u5b58\u653e\u7740\u6240\u6709 module \uff0cchunk\uff0c\u751f\u6210\u7684 asset \u4ee5\u53ca\u7528\u6765\u751f\u6210\u6700\u540e\u6253\u5305\u6587\u4ef6\u7684 template \u7684\u4fe1\u606f\u3002

\u3000\u30002. \u7f16\u8bd1\u4e0e\u6784\u5efa\u4e3b\u6d41\u7a0b

\u3000\u3000\u5728\u521b\u5efa module \u4e4b\u524d\uff0cCompiler \u4f1a\u89e6\u53d1 make\uff0c\u5e76\u8c03\u7528 Compilation.addEntry \u65b9\u6cd5\uff0c\u901a\u8fc7 options \u5bf9\u8c61\u7684 entry \u5b57\u6bb5\u627e\u5230\u6211\u4eec\u7684\u5165\u53e3js\u6587\u4ef6\u3002\u4e4b\u540e\uff0c\u5728 addEntry \u4e2d\u8c03\u7528\u79c1\u6709\u65b9\u6cd5 _addModuleChain \uff0c\u8fd9\u4e2a\u65b9\u6cd5\u4e3b\u8981\u505a\u4e86\u4e24\u4ef6\u4e8b\u60c5\u3002\u4e00\u662f\u6839\u636e\u6a21\u5757\u7684\u7c7b\u578b\u83b7\u53d6\u5bf9\u5e94\u7684\u6a21\u5757\u5de5\u5382\u5e76\u521b\u5efa\u6a21\u5757\uff0c\u4e8c\u662f\u6784\u5efa\u6a21\u5757\u3002

\u3000\u3000\u800c\u6784\u5efa\u6a21\u5757\u4f5c\u4e3a\u6700\u8017\u65f6\u7684\u4e00\u6b65\uff0c\u53c8\u53ef\u7ec6\u5316\u4e3a\u4e09\u6b65:

\u3000\u3000\u8c03\u7528\u5404 loader \u5904\u7406\u6a21\u5757\u4e4b\u95f4\u7684\u4f9d\u8d56

\u3000\u3000webpack \u63d0\u4f9b\u7684\u4e00\u4e2a\u5f88\u5927\u7684\u4fbf\u5229\u5c31\u662f\u80fd\u5c06\u6240\u6709\u8d44\u6e90\u90fd\u6574\u5408\u6210\u6a21\u5757\uff0c\u4e0d\u4ec5\u4ec5\u662f js \u6587\u4ef6\u3002\u6240\u4ee5\u9700\u8981\u4e00\u4e9b loader \uff0c\u6bd4\u5982 url-loader \uff0cjsx-loader \uff0c css-loader \u7b49\u7b49\u6765\u8ba9\u6211\u4eec\u53ef\u4ee5\u76f4\u63a5\u5728\u6e90\u6587\u4ef6\u4e2d\u5f15\u7528\u5404\u7c7b\u8d44\u6e90\u3002webpack \u8c03\u7528 doBuild() \uff0c\u5bf9\u6bcf\u4e00\u4e2a require() \u7528\u5bf9\u5e94\u7684 loader \u8fdb\u884c\u52a0\u5de5\uff0c\u6700\u540e\u751f\u6210\u4e00\u4e2a js module\u3002

\u3000\u3000Compilation.prototype._addModuleChain = function process(context, dependency, onModule, callback) {

\u3000\u3000var start = this.profile && +new Date();

\u3000\u3000...

\u3000\u3000// \u6839\u636e\u6a21\u5757\u7684\u7c7b\u578b\u83b7\u53d6\u5bf9\u5e94\u7684\u6a21\u5757\u5de5\u5382\u5e76\u521b\u5efa\u6a21\u5757

\u3000\u3000var moduleFactory = this.dependencyFactories.get(dependency.constructor);

\u3000\u3000...

\u3000\u3000moduleFactory.create(context, dependency, function(err, module) {

\u3000\u3000var result = this.addModule(module);

\u3000\u3000...

\u3000\u3000this.buildModule(module, function(err) {

\u3000\u3000...

\u3000\u3000// \u6784\u5efa\u6a21\u5757\uff0c\u6dfb\u52a0\u4f9d\u8d56\u6a21\u5757

\u3000\u3000}.bind(this));

\u3000\u3000}.bind(this));

\u3000\u3000};

\u3000\u3000\u8c03\u7528 acorn \u89e3\u6790\u7ecf loader \u5904\u7406\u540e\u7684\u6e90\u6587\u4ef6\u751f\u6210\u62bd\u8c61\u8bed\u6cd5\u6811 AST

\u3000\u3000Parser.prototype.parse = function parse(source, initialState) {

\u3000\u3000var ast;

\u3000\u3000if(!ast) {

\u3000\u3000// acorn\u4ee5es6\u7684\u8bed\u6cd5\u8fdb\u884c\u89e3\u6790

\u3000\u3000ast = acorn.parse(source, {

\u3000\u3000ranges: true,

\u3000\u3000locations: true,

\u3000\u3000ecmaVersion: 6,

\u3000\u3000sourceType: "module"

\u3000\u3000});

\u3000\u3000}

\u3000\u3000...

\u3000\u3000};

\u3000\u3000\u904d\u5386 AST\uff0c\u6784\u5efa\u8be5\u6a21\u5757\u6240\u4f9d\u8d56\u7684\u6a21\u5757

\u3000\u3000\u5bf9\u4e8e\u5f53\u524d\u6a21\u5757\uff0c\u6216\u8bb8\u5b58\u5728\u7740\u591a\u4e2a\u4f9d\u8d56\u6a21\u5757\u3002\u5f53\u524d\u6a21\u5757\u4f1a\u5f00\u8f9f\u4e00\u4e2a\u4f9d\u8d56\u6a21\u5757\u7684\u6570\u7ec4\uff0c\u5728\u904d\u5386 AST \u65f6\uff0c\u5c06 require() \u4e2d\u7684\u6a21\u5757\u901a\u8fc7addDependency() \u6dfb\u52a0\u5230\u6570\u7ec4\u4e2d\u3002\u5f53\u524d\u6a21\u5757\u6784\u5efa\u5b8c\u6210\u540e\uff0cwebpack \u8c03\u7528 processModuleDependencies \u5f00\u59cb\u9012\u5f52\u5904\u7406\u4f9d\u8d56\u7684 module\uff0c\u63a5\u7740\u5c31\u4f1a\u91cd\u590d\u4e4b\u524d\u7684\u6784\u5efa\u6b65\u9aa4\u3002

\u3000\u3000Compilation.prototype.addModuleDependencies = function(module, dependencies, bail, cacheGroup, recursive, callback) {

\u3000\u3000// \u6839\u636e\u4f9d\u8d56\u6570\u7ec4(dependencies)\u521b\u5efa\u4f9d\u8d56\u6a21\u5757\u5bf9\u8c61

\u3000\u3000var factories = [];

\u3000\u3000for(var i = 0; i < dependencies.length; i++) {

\u3000\u3000var factory = _this.dependencyFactories.get(dependencies[i][0].constructor);

\u3000\u3000factories[i] = [factory, dependencies[i]];

\u3000\u3000}

\u3000\u3000...

\u3000\u3000// \u4e0e\u5f53\u524d\u6a21\u5757\u6784\u5efa\u6b65\u9aa4\u76f8\u540c

\u3000\u3000}

\u3000\u30003. \u6784\u5efa\u7ec6\u8282

\u3000\u3000module \u662f webpack \u6784\u5efa\u7684\u6838\u5fc3\u5b9e\u4f53\uff0c\u4e5f\u662f\u6240\u6709 module\u7684 \u7236\u7c7b\uff0c\u5b83\u6709\u51e0\u79cd\u4e0d\u540c\u5b50\u7c7b\uff1aNormalModule , MultiModule ,ContextModule , DelegatedModule \u7b49\u3002\u4f46\u8fd9\u4e9b\u6838\u5fc3\u5b9e\u4f53\u90fd\u662f\u5728\u6784\u5efa\u4e2d\u90fd\u4f1a\u53bb\u8c03\u7528\u5bf9\u5e94\u65b9\u6cd5\uff0c\u4e5f\u5c31\u662f build() \u3002\u6765\u770b\u770b\u5176\u4e2d\u5177\u4f53\u505a\u4e86\u4ec0\u4e48:

\u3000\u3000// \u521d\u59cb\u5316module\u4fe1\u606f\uff0c\u5982context,id,chunks,dependencies\u7b49\u3002

\u3000\u3000NormalModule.prototype.build = function build(options, compilation, resolver, fs, callback) {

\u3000\u3000this.buildTimestamp = new Date().getTime(); // \u6784\u5efa\u8ba1\u65f6

\u3000\u3000this.built = true;

\u3000\u3000return this.doBuild(options, compilation, resolver, fs, function(err) {

\u3000\u3000// \u6307\u5b9a\u6a21\u5757\u5f15\u7528\uff0c\u4e0d\u7ecfacorn\u89e3\u6790

\u3000\u3000if(options.module && options.module.noParse) {

\u3000\u3000if(Array.isArray(options.module.noParse)) {

\u3000\u3000if(options.module.noParse.some(function(regExp) {

\u3000\u3000return typeof regExp === "string" ?

\u3000\u3000this.request.indexOf(regExp) === 0 :

\u3000\u3000regExp.test(this.request);

\u3000\u3000}, this)) return callback();

\u3000\u3000} else if(typeof options.module.noParse === "string" ?

\u3000\u3000this.request.indexOf(options.module.noParse) === 0 :

\u3000\u3000options.module.noParse.test(this.request)) {

\u3000\u3000return callback();

\u3000\u3000}

\u3000\u3000}

\u3000\u3000// \u7531acorn\u89e3\u6790\u751f\u6210ast

\u3000\u3000try {

\u3000\u3000this.parser.parse(this._source.source(), {

\u3000\u3000current: this,

\u3000\u3000module: this,

\u3000\u3000compilation: compilation,

\u3000\u3000options: options

\u3000\u3000});

\u3000\u3000} catch(e) {

\u3000\u3000var source = this._source.source();

\u3000\u3000this._source = null;

\u3000\u3000return callback(new ModuleParseError(this, source, e));

\u3000\u3000}

\u3000\u3000return callback();

\u3000\u3000}.bind(this));

\u3000\u3000};

\u3000\u3000\u5bf9\u4e8e\u6bcf\u4e00\u4e2a module \uff0c\u5b83\u90fd\u4f1a\u6709\u8fd9\u6837\u4e00\u4e2a\u6784\u5efa\u65b9\u6cd5\u3002\u5f53\u7136\uff0c\u5b83\u8fd8\u5305\u62ec\u4e86\u4ece\u6784\u5efa\u5230\u8f93\u51fa\u7684\u4e00\u7cfb\u5217\u7684\u6709\u5173 module \u751f\u547d\u5468\u671f\u7684\u51fd\u6570

几乎所有业务的开发构建都会用到 webpack 。的确,作为模块加载和打包神器,只需配置几个文件,加载各种 loader 就可以享受无痛流程化开发。但对于 webpack 这样一个复杂度较高的插件集合,它的整体流程及思想对我们来说还是很透明的。那么接下来我会带你了解 webpack 这样一个构建黑盒,首先来谈谈它的流程。   准备工作   1. webstorm 中配置 webpack-webstorm-debugger-script   在开始了解之前,必须要能对 webpack 整个流程进行 debug ,配置过程比较简单。   先将 webpack-webstorm-debugger-script 中的软件外包企业公司 置于 webpack.config.js 的同一目录下,搭建好你的脚手架后就可以直接 Debug 这个 webstorm-debugger.js 文件了。   2. webpack.config.js 配置   估计大家对 webpack.config.js 的配置也尝试过不少次了,这里就大致对这个配置文件进行个分析。   var path = require('path');   var node_modules = path.resolve(__dirname, 'node_modules');   var pathToReact = path.resolve(node_modules, 'react/dist/react.min.js');   module.exports = {   // 入口文件,是模块构建的起点,同时每一个入口文件对应最后生成的一个 chunk。   entry: {   bundle: [   'webpack/hot/dev-server',   'webpack-dev-server/client?',   path.resolve(__dirname, 'app/app.js')   ],   },   // 文件路径指向(可加快打包过程)。   resolve: {   alias: {   'react': pathToReact   }   },   // 生成文件,是模块构建的终点,包括输出文件与输出路径。   output: {   path: path.resolve(__dirname, 'build'),   filename: '[name].js',   },   // 这里配置了处理各模块的 loader ,包括 css 预处理 loader ,es6 编译 loader,图片处理 loader。   module: {   loaders: [   {   test: /\.js$/,   loader: 'babel',   query: {   presets: ['es2015', 'react']   }   }   ],   noParse: [pathToReact]   },   // webpack 各插件对象,在 webpack 的事件流中执行对应的方法。   plugins: [   new webpack.HotModuleReplacementPlugin();   ]   };   除此之外再大致介绍下 webpack 的一些核心概念:   loader : 能转换各类资源,并处理成对应模块的加载器。loader 间可以串行使用。   chunk : code splitting后的产物,也就是按需加载的分块,装载了不同的module。   对于module和chunk的关系可以参照webpack官方的这张图:   plugin : webpack 的插件实体,这里以 UglifyJsPlugin 为例。   function UglifyJsPlugin(options) {   this.options = options;   }   module.exports = UglifyJsPlugin;   UglifyJsPlugin.prototype.apply = function(compiler) {   compiler.plugin("compilation", function(compilation) {   compilation.plugin("build-module", function(module) {   });   compilation.plugin("optimize-chunk-assets", function(chunks, callback) {   // Uglify 逻辑   });   compilation.plugin("normal-module-loader", function(context) {   });   });   };   在 webpack 中你经常可以看到 compilation.plugin('xxx', callback) ,你可以把它当作是一个事件的绑定,这些事件在打包时由 webpack 来触发。   3. 流程总览   在具体流程学习前,可以先通过这幅 webpack整体流程图 了解一下大致流程(建议保存下来查看)。   shell 与 config 解析   每次在命令行输入 webpack 后,操作系统都会去调用 ./node_modules/.bin/webpack 这个 shell 脚本。这个脚本会去调用./node_modules/webpack/bin/webpack.js 并追加输入的参数,如 -p , -w 。(图中 webpack.js 是 webpack 的启动文件,而 $@ 是后缀参数)   在 webpack.js 这个文件中 webpack 通过 optimist 将用户配置的 webpack.config.js 和 shell 脚本传过来的参数整合成 options 对象传到了下一个流程的控制对象中。   1. optimist   和 commander 一样,optimist 实现了 node 命令行的解析,其 API 调用非常方便。   var optimist = require("optimist");   optimist   .boolean("json").alias("json", "j").describe("json")   .boolean("colors").alias("colors", "c").describe("colors")   .boolean("watch").alias("watch", "w").describe("watch")   ...   获取到后缀参数后,optimist 分析参数并以键值对的形式把参数对象保存在 optimist.argv 中,来看看 argv 究竟有什么?   // webpack --hot -w   {   hot: true,   profile: false,   watch: true,   ...   }   2. config 合并与插件加载   在加载插件之前,webpack 将 webpack.config.js 中的各个配置项拷贝到 options 对象中,并加载用户配置在 webpack.config.js 的 plugins 。接着 optimist.argv 会被传入到 ./node_modules/webpack/bin/convert-argv.js 中,通过判断 argv 中参数的值决定是否去加载对应插件。(至于 webpack 插件运行机制,在之后的运行机制篇会提到)   ifBooleanArg("hot", function() {   ensureArray(options, "plugins");   var HotModuleReplacementPlugin = require("../lib/HotModuleReplacementPlugin");   options.plugins.push(new HotModuleReplacementPlugin());   });   ...   return options;   options 作为最后返回结果,包含了之后构建阶段所需的重要信息。   {   entry: {},//入口配置   output: {}, //输出配置   plugins: [], //插件集合(配置文件 + shell指令)   module: { loaders: [ [Object] ] }, //模块配置   context: //工程路径   ...   }   这和 webpack.config.js 的配置非常相似,只是多了一些经 shell 传入的插件对象。插件对象一初始化完毕, options 也就传入到了下个流程中。   var webpack = require("../lib/webpack.js");   var compiler = webpack(options);   编译与构建流程   在加载配置文件和 shell 后缀参数申明的插件,并传入构建信息 options 对象后,开始整个 webpack 打包最漫长的一步。而这个时候,真正的 webpack 对象才刚被初始化,具体的初始化逻辑在 lib/webpack.js 中,如下:   function webpack(options) {   var compiler = new Compiler();   ...// 检查options,若watch字段为true,则开启watch线程   return compiler;   }   ...   webpack 的实际入口是 Compiler 中的 run 方法,run 一旦执行后,就开始了编译和构建流程 ,其中有几个比较关键的 webpack 事件节点。   compile 开始编译   make 从入口点分析模块及其依赖的模块,创建这些模块对象   build-module 构建模块   after-compile 完成构建   seal 封装构建结果   emit 把各个chunk输出到结果文件   after-emit 完成输出   1. 核心对象 Compilation   compiler.run 后首先会触发 compile ,这一步会构建出 Compilation 对象:   compilation类图   这个对象有两个作用,一是负责组织整个打包过程,包含了每个构建环节及输出环节所对应的方法,可以从图中看到比较关键的步骤,如 addEntry() , _addModuleChain() , buildModule() , seal() , createChunkAssets() (在每一个节点都会触发 webpack 事件去调用各插件)。二是该对象内部存放着所有 module ,chunk,生成的 asset 以及用来生成最后打包文件的 template 的信息。   2. 编译与构建主流程   在创建 module 之前,Compiler 会触发 make,并调用 Compilation.addEntry 方法,通过 options 对象的 entry 字段找到我们的入口js文件。之后,在 addEntry 中调用私有方法 _addModuleChain ,这个方法主要做了两件事情。一是根据模块的类型获取对应的模块工厂并创建模块,二是构建模块。   而构建模块作为最耗时的一步,又可细化为三步:   调用各 loader 处理模块之间的依赖   webpack 提供的一个很大的便利就是能将所有资源都整合成模块,不仅仅是 js 文件。所以需要一些 loader ,比如 url-loader ,jsx-loader , css-loader 等等来让我们可以直接在源文件中引用各类资源。webpack 调用 doBuild() ,对每一个 require() 用对应的 loader 进行加工,最后生成一个 js module。   Compilation.prototype._addModuleChain = function process(context, dependency, onModule, callback) {   var start = this.profile && +new Date();   ...   // 根据模块的类型获取对应的模块工厂并创建模块   var moduleFactory = this.dependencyFactories.get(dependency.constructor);   ...   moduleFactory.create(context, dependency, function(err, module) {   var result = this.addModule(module);   ...   this.buildModule(module, function(err) {   ...   // 构建模块,添加依赖模块   }.bind(this));   }.bind(this));   };   调用 acorn 解析经 loader 处理后的源文件生成抽象语法树 AST   Parser.prototype.parse = function parse(source, initialState) {   var ast;   if(!ast) {   // acorn以es6的语法进行解析   ast = acorn.parse(source, {   ranges: true,   locations: true,   ecmaVersion: 6,   sourceType: "module"   });   }   ...   };   遍历 AST,构建该模块所依赖的模块   对于当前模块,或许存在着多个依赖模块。当前模块会开辟一个依赖模块的数组,在遍历 AST 时,将 require() 中的模块通过addDependency() 添加到数组中。当前模块构建完成后,webpack 调用 processModuleDependencies 开始递归处理依赖的 module,接着就会重复之前的构建步骤。   Compilation.prototype.addModuleDependencies = function(module, dependencies, bail, cacheGroup, recursive, callback) {   // 根据依赖数组(dependencies)创建依赖模块对象   var factories = [];   for(var i = 0; i < dependencies.length; i++) {   var factory = _this.dependencyFactories.get(dependencies[i][0].constructor);   factories[i] = [factory, dependencies[i]];   }   ...   // 与当前模块构建步骤相同   }   3. 构建细节   module 是 webpack 构建的核心实体,也是所有 module的 父类,它有几种不同子类:NormalModule , MultiModule ,ContextModule , DelegatedModule 等。但这些核心实体都是在构建中都会去调用对应方法,也就是 build() 。来看看其中具体做了什么:   // 初始化module信息,如context,id,chunks,dependencies等。   NormalModule.prototype.build = function build(options, compilation, resolver, fs, callback) {   this.buildTimestamp = new Date().getTime(); // 构建计时   this.built = true;   return this.doBuild(options, compilation, resolver, fs, function(err) {   // 指定模块引用,不经acorn解析   if(options.module && options.module.noParse) {   if(Array.isArray(options.module.noParse)) {   if(options.module.noParse.some(function(regExp) {   return typeof regExp === "string" ?   this.request.indexOf(regExp) === 0 :   regExp.test(this.request);   }, this)) return callback();   } else if(typeof options.module.noParse === "string" ?   this.request.indexOf(options.module.noParse) === 0 :   options.module.noParse.test(this.request)) {   return callback();   }   }   // 由acorn解析生成ast   try {   this.parser.parse(this._source.source(), {   current: this,   module: this,   compilation: compilation,   options: options   });   } catch(e) {   var source = this._source.source();   this._source = null;   return callback(new ModuleParseError(this, source, e));   }   return callback();   }.bind(this));   };   对于每一个 module ,它都会有这样一个构建方法。当然,它还包括了从构建到输出的一系列的有关 module 生命周期的函数

  • webpack宸ヤ綔娴佺▼
    绛旓細Webpack 鐨杩愯娴佺▼鏄涓涓覆琛岀殑杩囩▼,浠庡惎鍔ㄥ埌缁撴潫浼氫緷娆鎵ц浠ヤ笅娴佺▼ :1.鍒濆鍖栧弬鏁帮細浠庨厤缃枃浠跺拰 Shell 璇彞涓鍙栦笌鍚堝苟鍙傛暟,寰楀嚭鏈缁堢殑鍙傛暟銆2.寮濮嬬紪璇戯細鐢ㄤ笂涓姝ュ緱鍒扮殑鍙傛暟鍒濆鍖 Compiler 瀵硅薄,鍔犺浇鎵鏈夐厤缃殑鎻掍欢,鎵ц瀵硅薄鐨 run 鏂规硶寮濮嬫墽琛岀紪璇戙3.纭畾鍏ュ彛锛氭牴鎹厤缃腑鐨 entry 鎵惧嚭鎵鏈夌殑...
  • webpack鎵ц鏈哄埗娴佺▼鏄庝箞鏍风殑
    绛旓細webstorm 涓厤缃 webpack-webstorm-debugger-script 鍦ㄥ紑濮嬩簡瑙d箣鍓,蹇呴』瑕佽兘瀵 webpack 鏁翠釜娴佺▼杩涜 debug ,閰嶇疆杩囩▼姣旇緝绠鍗曘 鍏堝皢 webpack-webstorm-debugger-script 涓殑杞欢澶栧寘浼佷笟鍏徃 缃簬 webpack.config.js 鐨勫悓涓鐩綍涓,鎼缓濂戒綘鐨勮剼鎵嬫灦鍚庡氨鍙互鐩存帴 Debug 杩欎釜 webstorm-debugger.js 鏂囦欢浜嗐 2. ...
  • jS瀛︿範绗旇
    绛旓細Webpack鐨勬梾绋嬩粠鍒涘缓涓涓疄渚嬪紑濮嬶紝閫氳繃webpack(options)锛屽畠鐏垫椿鍦版敮鎸侀潤鎬侀厤缃璞″拰鍔ㄦ佸嚱鏁板紡椤甸潰鏋勫缓銆傛瀯寤杩囩▼鍒嗕负涓ゅぇ鍏抽敭姝ラ锛歮ake闃舵璐熻矗鎵цcompilation鏋勫缓锛岃宻ear闃舵鍒欒仛鐒︿簬chunk鐨勪紭鍖栫敓鎴愩傚湪浜嬩欢椹卞姩鐨勪笘鐣岄噷锛宔ventemitter鍜孴apable鎼烘墜鍚堜綔锛屾彁渚涗簡涓板瘜鐨勬彃浠舵寕杞界偣銆俢hunk鏄ā鍧楀鐢ㄧ殑鍩虹煶锛...
  • webpack鏄浠涔
    绛旓細Webpack鐨鎵ц杩囩▼Webpack浠庢潯鐩紙entry锛夊紑濮嬪伐浣滐紝閫氬父杩欎簺鏄疛avaScript妯″潡锛屽叾涓webpack寮濮嬪叾閬嶅巻杩囩▼銆傚湪姝よ繃绋嬩腑锛寃ebpack浼氭牴鎹姞杞藉櫒閰嶇疆璇勪及鏉$洰锛坋ntry锛夊尮閰嶏紝杩欎簺閰嶇疆鍛婅瘔webpack濡備綍杞崲姣忎釜鍖归厤銆傝В鏋娴佺▼鏉$洰锛坋ntry锛夋湰韬氨鏄竴涓ā鍧椼傚綋webpack閬囧埌涓涓潯鐩椂锛寃ebpack浼氬皾璇曚娇鐢ㄦ潯鐩殑resolve...
  • 婧愮爜缁嗚-娣卞叆浜嗚Вterser-webpack-plugin鐨勫疄鐜
    绛旓細绱ф帴鐫锛岄亶鍘嗘瘡涓涓 assetNames锛屼竴涓釜浠诲姟琚 scheduleTask 鍑嗗灏辩华锛岀瓑寰呯潃鎵ц銆備换鍔″垎瑙</ 鑰屾瘡涓换鍔$殑鏍稿績 scheduleTask锛屽氨鍍忔媶瑙h皽棰樹竴鑸紝鍖呭惈鐫鑾峰彇 asset 淇℃伅銆佷唬鐮佹鏌ャ乵inify 鐨勯夋嫨锛圵orker 鎴栦富绾跨▼锛夈佹柊浠g爜鐢熸垚鍜岀紦瀛樻洿鏂帮紝浠ュ強瀵硅祫浜у唴瀹圭殑鍗虫椂鏇存柊銆傛暣涓杩囩▼绱у噾鑰屾湁搴忥紝浠ヨ祫婧愬鐞...
  • 鎬庢牱浣跨敤webpack婧愮爜loader鏈哄埗
    绛旓細loader鐢ㄦ硶閰嶇疆module: { rules: [ { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader' } ] } ] }鍐呰仈import Styles from 'style-loader!css-loader?modules!./styles.css';CLIwebpack --module-bind 'css=style-loader!
  • webpack鎵撳寘鍘熺悊
    绛旓細webpack鎵撳寘鍘熺悊鏄牴鎹枃浠堕棿鐨勪緷璧栧叧绯诲鍏惰繘琛岄潤鎬佸垎鏋愶紝鐒跺悗灏嗚繖浜涙ā鍧楁寜鎸囧畾瑙勫垯鐢熸垚闈欐佽祫婧愶紝褰 webpack 澶勭悊绋嬪簭鏃讹紝瀹冧細閫掑綊鍦版瀯寤轰竴涓緷璧栧叧绯诲浘(dependency graph)锛屽叾涓寘鍚簲鐢ㄧ▼搴忛渶瑕佺殑姣忎釜妯″潡锛岀劧鍚庡皢鎵鏈夎繖浜涙ā鍧楁墦鍖呮垚涓涓垨澶氫釜 bundle銆倃ebpack鏈変袱绉嶇粍缁囨ā鍧楃殑渚濊禆鏂瑰紡锛屽悓姝ャ佸紓姝ャ傚紓姝...
  • webpack 鎺㈢储-entry 鍜宱utput璇﹁В
    绛旓細涓婂浘涓叆鍙e氨鏄乏涓婅鐨.js鏂囦欢銆傝繖閮ㄥ垎璇︾粏鍙互鍙傝Webpack瀹樼綉锛岃繖閲岃繖鏄瑪鑰呰瘯鐐兼椂鍋氱殑绗旇銆傚崢鍏ュ彛鏈変袱绉嶅啓娉曪細娉ㄦ剰锛屽鏋滄病鏈夐厤缃畂utput鐨刦ilename锛屼笂杈规瀯寤哄嚭鏉ョ殑dist涓枃浠跺悕鏄痠ndex.js銆傛敞鎰忥細涓婅堪澶氬叆鍙fā寮忎笅锛屾墦鍑烘潵鐨勫寘鏈変袱涓枃浠讹細index.js鍜宧ello.js锛屽氨鏄搴攅ntry瀵硅薄鐨刱ey銆傝屾墦鍖呭嚭鏉...
  • Webpack鎬庢牱鎿嶄綔缂撳瓨
    绛旓細浜屻webpack 鍚姩杩愯鐨 runtime 浠g爜:鐪嬭繃鎴戜箣鍓嶇殑鏂囩珷:娣卞叆鐞嗚В webpack 鏂囦欢鎵撳寘鏈哄埗 灏变細鐭ラ亾,鍦 webpack 鍚姩鐨勬椂鍊欓渶瑕鎵ц涓浜涘惎鍔ㄤ唬鐮併(function(modules) { window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) { // ... }; function __webpack_require__(moduleId)...
  • 鎻掍欢鏈哄埗璇﹁В
    绛旓細鎻掍欢妯″紡鏄竴绉嶅簲鐢ㄩ潪甯稿箍娉涚殑妯″紡銆傛垜浠敤鐨勫緢澶氳蒋浠堕兘鎷ユ湁鑷韩鐨勬彃浠鏈哄埗锛岄氳繃鎻掍欢鍙互鎷撳睍杞欢鐨勫姛鑳姐傚彟澶栵紝鎻掍欢妯″紡涔熷箍娉涘簲鐢ㄤ簬 web 鏂归潰銆備緥濡 Webpack銆 Vue CLI銆乁MI銆丅abel绛夈傞偅涔堟彃浠剁郴缁熸槸濡備綍瀹炵幇鐨勫憿锛熷涓婂浘鎵绀猴紝鎻掍欢搴旂敤鐨娴佺▼寰堢畝鍗曪細鍏朵腑锛岀 3 姝ョ殑鏃跺欙紝鍥炲幓璋冪敤鎻掍欢锛岃皟鐢ㄦ彃浠舵椂...
  • 扩展阅读:手机webp批量转换jpg ... webpack的构建流程 ... 手机webp看图器 ... webpack热更新原理 面试 ... webpack打包流程面试 ... webpack打包流程图 ... webpack工作流程 ... webpack面试题及答案 ... webpack基本配置详解 ...

    本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网