├── plugins ├── test.js ├── common.js ├── readme.md ├── index.js ├── test │ └── test.js ├── index.html └── webpack.config.js ├── require ├── src │ ├── c │ │ └── c.js │ ├── a.js │ └── b.js ├── webpack.config.js └── index.js ├── entry ├── index.js ├── index1.js ├── index.html └── webpack.config.js ├── code_split ├── split.js ├── index.html ├── index.js ├── readme.md ├── webpack.config.js └── dist │ └── index.js ├── .gitignore ├── loaders ├── test.scss ├── readme.md ├── test │ └── test.js ├── index.js ├── index.html └── webpack.config.js ├── scope-hoisting ├── build.js ├── lazy.js ├── graph.png ├── graph2.png ├── graph3.png ├── example.js ├── webpack.config.js ├── js │ ├── 0.output.js │ └── output.js ├── template.md ├── graph.svg ├── graph2.svg ├── graph3.svg └── README.md ├── write-plugins ├── test.js └── index.js ├── modules ├── split.js ├── index.html ├── index.js ├── readme.md └── webpack.config.js ├── resolve ├── split.js ├── test │ ├── test.js │ └── test │ │ └── test.js ├── index.html ├── index.js ├── readme.md └── webpack.config.js ├── devtool ├── readme.md ├── test │ └── test.js ├── index.js ├── index.html └── webpack.config.js ├── output ├── index1.js ├── index.html ├── uuudist │ ├── 5df_dynamic.js │ ├── _index10c1.js │ └── _index16f.js ├── index.js ├── readme.md └── webpack.config.js ├── .babelrc ├── write-loaders └── index.js ├── README.md ├── webpack.config.js ├── command.js ├── doc └── readme.md ├── package.json ├── test.js └── demo.webpack.config.js /plugins/test.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /require/src/c/c.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /entry/index.js: -------------------------------------------------------------------------------- 1 | class A {} -------------------------------------------------------------------------------- /plugins/common.js: -------------------------------------------------------------------------------- 1 | module.exports =1 -------------------------------------------------------------------------------- /require/src/a.js: -------------------------------------------------------------------------------- 1 | export const a = 1; -------------------------------------------------------------------------------- /require/src/b.js: -------------------------------------------------------------------------------- 1 | export const b = 1; -------------------------------------------------------------------------------- /entry/index1.js: -------------------------------------------------------------------------------- 1 | console.log('I am index1') -------------------------------------------------------------------------------- /code_split/split.js: -------------------------------------------------------------------------------- 1 | console.log('I am a split') -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | dist -------------------------------------------------------------------------------- /loaders/test.scss: -------------------------------------------------------------------------------- 1 | body{ 2 | background:yellow 3 | } -------------------------------------------------------------------------------- /scope-hoisting/build.js: -------------------------------------------------------------------------------- 1 | require("../build-common"); -------------------------------------------------------------------------------- /write-plugins/test.js: -------------------------------------------------------------------------------- 1 | const a = 1; 2 | exports.a = a; -------------------------------------------------------------------------------- /modules/split.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | export const split= { 5 | a:1 6 | } -------------------------------------------------------------------------------- /resolve/split.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | export const split= { 5 | a:1 6 | } -------------------------------------------------------------------------------- /devtool/readme.md: -------------------------------------------------------------------------------- 1 | https://webpack.js.org/configuration/devtool/#devtool -------------------------------------------------------------------------------- /loaders/readme.md: -------------------------------------------------------------------------------- 1 | https://webpack.js.org/configuration/devtool/#devtool -------------------------------------------------------------------------------- /plugins/readme.md: -------------------------------------------------------------------------------- 1 | https://webpack.js.org/configuration/devtool/#devtool -------------------------------------------------------------------------------- /output/index1.js: -------------------------------------------------------------------------------- 1 | console.log('index54245234451.js'); 2 | 3 | module.exports =1 -------------------------------------------------------------------------------- /plugins/index.js: -------------------------------------------------------------------------------- 1 | 2 | import test from 'test'; 3 | 4 | alert($.ajax); 5 | -------------------------------------------------------------------------------- /loaders/test/test.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | module.exports = ()=>{ 5 | return 'test' 6 | } -------------------------------------------------------------------------------- /devtool/test/test.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | module.exports = ()=>{ 5 | console.log('test') 6 | } -------------------------------------------------------------------------------- /plugins/test/test.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | module.exports = ()=>{ 5 | console.log('test') 6 | } -------------------------------------------------------------------------------- /resolve/test/test.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | module.exports = ()=>{ 5 | console.log('test') 6 | } -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "stage-0" 5 | ] 6 | } -------------------------------------------------------------------------------- /devtool/index.js: -------------------------------------------------------------------------------- 1 | 2 | import test from 'test'; 3 | debugger; 4 | console.log(test()); 5 | -------------------------------------------------------------------------------- /resolve/test/test/test.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | module.exports = ()=>{ 5 | console.log('test') 6 | } -------------------------------------------------------------------------------- /scope-hoisting/lazy.js: -------------------------------------------------------------------------------- 1 | export * from "c"; 2 | import * as d from "d"; 3 | export { d }; 4 | -------------------------------------------------------------------------------- /loaders/index.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | require('./test.scss'); 5 | import test from 'test'; 6 | alert(test()); 7 | -------------------------------------------------------------------------------- /scope-hoisting/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slashhuang/webpack2-tutorial/HEAD/scope-hoisting/graph.png -------------------------------------------------------------------------------- /scope-hoisting/graph2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slashhuang/webpack2-tutorial/HEAD/scope-hoisting/graph2.png -------------------------------------------------------------------------------- /scope-hoisting/graph3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slashhuang/webpack2-tutorial/HEAD/scope-hoisting/graph3.png -------------------------------------------------------------------------------- /output/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /devtool/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /modules/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resolve/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /code_split/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /loaders/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /entry/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | > -------------------------------------------------------------------------------- /require/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: { 3 | index: './index.js' 4 | }, 5 | output: { 6 | filename : '[name]-[id].js', 7 | hashDigestLength : 4 8 | } 9 | } -------------------------------------------------------------------------------- /output/uuudist/5df_dynamic.js: -------------------------------------------------------------------------------- 1 | webpackJsonpMyLibrary([0,1],[ 2 | /* 0 */ 3 | /***/ (function(module, exports) { 4 | 5 | console.log('index54245234451.js'); 6 | 7 | module.exports =1 8 | 9 | /***/ }) 10 | ]); -------------------------------------------------------------------------------- /resolve/index.js: -------------------------------------------------------------------------------- 1 | console.log('I am index') 2 | 3 | // import test from 'test'; 4 | const test = require('test') 5 | class S { 6 | constructor(){ 7 | this.a = 'a ' 8 | } 9 | } 10 | console.log(test()); 11 | -------------------------------------------------------------------------------- /plugins/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /output/index.js: -------------------------------------------------------------------------------- 1 | console.log('I am index') 2 | 3 | //require.ensure(dependencies: String[], callback: function(require), chunkName: String) 4 | 5 | //异步加载 6 | require.ensure([],(require)=>{ 7 | require('./index1.js') 8 | },'dynamic') -------------------------------------------------------------------------------- /scope-hoisting/example.js: -------------------------------------------------------------------------------- 1 | import { a, x, y } from "a"; 2 | import * as b from "b"; 3 | 4 | // import("./lazy").then(function(lazy) { 5 | var lazy ={}; 6 | console.log(a, b.a(), x, y, lazy.c, lazy.d.a, lazy.x, lazy.y); 7 | // }); 8 | -------------------------------------------------------------------------------- /write-loaders/index.js: -------------------------------------------------------------------------------- 1 | module.exports = function(content) { 2 | console.log('we are preprocess assets content with\n', content); 3 | let newContent = `${content}; console.log("author by slashhuang")`; 4 | return newContent 5 | }; -------------------------------------------------------------------------------- /scope-hoisting/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path =require('path'); 2 | module.exports = { 3 | entry: { 4 | example: './example', 5 | }, 6 | output: { 7 | path: path.resolve(__dirname, 'dist'), 8 | filename: '[name].js' 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /code_split/index.js: -------------------------------------------------------------------------------- 1 | // export import 2 | // amd 3 | // require 4 | 5 | console.log('I am index') 6 | 7 | // require.ensure(dependencies: String[], callback: function(require), chunkName: String) 8 | 9 | require('./split'); 10 | // import * as Test from './split.js'; -------------------------------------------------------------------------------- /entry/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path =require('path'); 2 | module.exports = { 3 | entry:{ 4 | index:'./index.js', 5 | index1:'./index1.js' 6 | }, 7 | output: { 8 | path: path.resolve(__dirname, 'dist'), 9 | filename: '_[name].js' 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /modules/index.js: -------------------------------------------------------------------------------- 1 | console.log('I am index') 2 | 3 | //require.ensure(dependencies: String[], callback: function(require), chunkName: String) 4 | import { split } from './split'; 5 | 6 | class S { 7 | constructor(){ 8 | this.a = 'a ' 9 | } 10 | } 11 | 12 | alert(new S()) 13 | console.log(split); 14 | -------------------------------------------------------------------------------- /require/index.js: -------------------------------------------------------------------------------- 1 | var context = require.context('./src',false); 2 | let a = context('./a').a; 3 | 4 | // import { a } from './src/a'; 5 | import { b } from './src/b'; 6 | 7 | var id = require.resolve('./src/a'); 8 | if (id === 0) { 9 | console.log('1st') 10 | } else { 11 | console.log('not 1st') 12 | } 13 | console.log(a + b); -------------------------------------------------------------------------------- /code_split/readme.md: -------------------------------------------------------------------------------- 1 | Template Description 2 | [hash] 3 | The hash of the module identifier 4 | [chunkhash] 5 | The hash of the chunk content 6 | [name] 7 | The module name 8 | [id] 9 | The module identifier 10 | [file] 11 | The module filename 12 | [filebase] 13 | The module basename 14 | [query] 15 | The module query, i.e., the string following ? in the filename -------------------------------------------------------------------------------- /modules/readme.md: -------------------------------------------------------------------------------- 1 | Template Description 2 | [hash] 3 | The hash of the module identifier 4 | [chunkhash] 5 | The hash of the chunk content 6 | [name] 7 | The module name 8 | [id] 9 | The module identifier 10 | [file] 11 | The module filename 12 | [filebase] 13 | The module basename 14 | [query] 15 | The module query, i.e., the string following ? in the filename -------------------------------------------------------------------------------- /output/readme.md: -------------------------------------------------------------------------------- 1 | Template Description 2 | [hash] 3 | The hash of the module identifier 4 | [chunkhash] 5 | The hash of the chunk content 6 | [name] 7 | The module name 8 | [id] 9 | The module identifier 10 | [file] 11 | The module filename 12 | [filebase] 13 | The module basename 14 | [query] 15 | The module query, i.e., the string following ? in the filename -------------------------------------------------------------------------------- /resolve/readme.md: -------------------------------------------------------------------------------- 1 | Template Description 2 | [hash] 3 | The hash of the module identifier 4 | [chunkhash] 5 | The hash of the chunk content 6 | [name] 7 | The module name 8 | [id] 9 | The module identifier 10 | [file] 11 | The module filename 12 | [filebase] 13 | The module basename 14 | [query] 15 | The module query, i.e., the string following ? in the filename -------------------------------------------------------------------------------- /write-plugins/index.js: -------------------------------------------------------------------------------- 1 | class consolePlugin { 2 | apply(compiler) { 3 | compiler.plugin('compilation', function(compilation, callback) { 4 | console.log("we are compiling assets --------\n\n\n"); 5 | // Invokes webpack provided callback after functionality is complete. 6 | }); 7 | } 8 | } 9 | module.exports = consolePlugin; -------------------------------------------------------------------------------- /output/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | const path =require('path'); 3 | let base = { 4 | index:'./index.js?t=2', 5 | index1:'./index1.js' 6 | }; 7 | 8 | //webpack2 提供了多种配置方案 9 | 10 | module.exports = { 11 | entry:base, 12 | output: { 13 | //导出目录 14 | path: path.resolve(__dirname, 'uuudist'), 15 | publicPath: "/output/uuudist/", // server-relative 16 | //包规范格式 17 | libraryTarget:'umd', 18 | library: "MyLibrary", 19 | //文件名 20 | chunkFilename:'[chunkhash]_[name].js', 21 | //hash位数 22 | hashDigestLength:3, 23 | //导出文件 24 | //hash ==> webpack编译过程 25 | // chunkhash => webpack对每个文件的hash 26 | filename: '_[name][chunkhash].js' 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /code_split/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | const path =require('path'); 3 | let base = { 4 | index:'./index.js', 5 | }; 6 | 7 | //webpack2 提供了多种配置方案 8 | const dynamic_entry = ()=>base; 9 | 10 | const dynamic_entry_promise=()=>{ 11 | return new Promise((resolve,reject)=>{ 12 | resolve(base) 13 | }) 14 | } 15 | 16 | module.exports = { 17 | entry:base, 18 | output: { 19 | //导出目录 20 | path: path.resolve(__dirname, 'dist'), 21 | publicPath: "/dist/", // server-relative 22 | //包规范格式 23 | libraryTarget:'umd', 24 | library: "MyLibrary", 25 | //文件名 26 | chunkFilename:'[chunkhash]_[id].js', 27 | //hash位数 28 | hashDigestLength:2, 29 | //导出文件 30 | filename: '[name].js' 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /resolve/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | const path =require('path'); 3 | let base = { 4 | index:'./index.js', 5 | }; 6 | 7 | //webpack2 提供了多种配置方案 8 | 9 | module.exports = { 10 | entry:base, 11 | output: { 12 | path: path.resolve(__dirname, 'dist'), 13 | filename: '[name].js' 14 | }, 15 | resolve:{ 16 | alias:{ 17 | test:path.resolve(__dirname,'test/test/test.js') 18 | } 19 | }, 20 | //entry ==> rules ===> webpack ==> output 21 | module:{ 22 | rules:[ 23 | { 24 | test: /\.jsx?$/, 25 | 26 | exclude: [ 27 | 'node_modules' 28 | ], 29 | use:[{ 30 | loader: "babel-loader", 31 | }] 32 | }, 33 | ] 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /modules/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | const path =require('path'); 3 | let base = { 4 | index:'./index.js', 5 | }; 6 | 7 | //webpack2 提供了多种配置方案 8 | 9 | 10 | module.exports = { 11 | entry:base, 12 | output: { 13 | path: path.resolve(__dirname, 'dist'), 14 | filename: '[name].js' 15 | }, 16 | module:{ 17 | rules:[ 18 | // Conditions, Results and nested Rules. 19 | { 20 | test: /\.jsx?$/, 21 | 22 | exclude: [ 23 | 'node_modules' 24 | ], 25 | // flags to apply these rules, even if they are overridden (advanced option) 26 | // loader: "babel-loader", 27 | // rule.use是数组形式和rule.loaders是它的别名 28 | use:[{ 29 | loader: "babel-loader", 30 | }] 31 | }, 32 | ] 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /devtool/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | const path =require('path'); 3 | let base = { 4 | index:'./index.js', 5 | }; 6 | 7 | module.exports = { 8 | // https://webpack.js.org/configuration/devtool/#devtool 9 | devtool:'source-map', 10 | // https://webpack.js.org/configuration/target/#target 11 | target:"web", 12 | entry:base, 13 | output: { 14 | path: path.resolve(__dirname, 'dist'), 15 | filename: '[name].js' 16 | }, 17 | resolve:{ 18 | alias:{ 19 | test:path.resolve(__dirname,'test/test.js') 20 | } 21 | }, 22 | module:{ 23 | rules:[ 24 | { 25 | test: /\.jsx?$/, 26 | 27 | exclude: [ 28 | 'node_modules' 29 | ], 30 | use:[{ 31 | loader: "babel-loader", 32 | }] 33 | }, 34 | ] 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## webpack2-tutorial 3 | 4 | > webpack2 教程 5 | [官方github](https://github.com/webpack/webpack) 6 | 7 | ```bash 8 | $ npm install 9 | ``` 10 | 11 | ## Usage 使用 12 | 13 | ```bash 14 | 15 | $ git clone git@github.com:slashhuang/webpack-tutorial.git 16 | 17 | # run the following npm scripts to learn webpack2 18 | 19 | npm run entry 20 | 21 | "scripts": { 22 | "entry": "node ./command.js -f=entry", 23 | "output": "node ./command.js -f=output", 24 | "split": "node ./command.js -f=code_split", 25 | "module": "node ./command.js -f=modules", 26 | "resolve": "node ./command.js -f=resolve", 27 | "devtool": "node ./command.js -f=devtool", 28 | "loaders": "node ./command.js -f=loaders", 29 | "plugins": "node ./command.js -f=plugins" 30 | } 31 | 32 | ``` 33 | 34 | ## 参考资料 35 | 36 | 1. [webpack2参考资料](https://webpack.js.org/) 37 | 38 | 39 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const consolePlugin = require('./write-plugins'); 2 | const customizeLoader = require('./write-loaders'); 3 | const path = require('path'); 4 | 5 | module.exports = { 6 | entry:{ 7 | test: "./write-plugins/test.js" 8 | }, 9 | output: { 10 | path: path.resolve(__dirname, 'dist'), 11 | filename: '[name].js' 12 | }, 13 | resolveLoader: { 14 | alias: { 15 | 'c-loader': path.resolve(__dirname,'write-loaders/index.js'), 16 | } 17 | }, 18 | resolve:{ 19 | alias:{ 20 | test:path.resolve(__dirname,'test/test.js'), 21 | } 22 | }, 23 | module:{ 24 | rules:[ 25 | { 26 | test: /\.jsx?$/, 27 | exclude: [ 28 | 'node_modules' 29 | ], 30 | use:[{ 31 | loader: "babel-loader", 32 | },{loader: "c-loader"}] 33 | }, 34 | ] 35 | }, 36 | plugins: [ 37 | new consolePlugin(), 38 | ] 39 | }; -------------------------------------------------------------------------------- /command.js: -------------------------------------------------------------------------------- 1 | /** 2 | * built by slashhuang 3 | * 17/4/9 4 | */ 5 | const path= require('path'); 6 | const webpack = require('webpack'); 7 | const yargs = require('yargs'); 8 | const exec = require('child_process').execSync; 9 | let folder = yargs.argv['f']; 10 | 11 | const configFile = require(`./${folder}/webpack.config.js`); 12 | configFile.context = path.resolve(process.cwd(),`./${folder}/`); 13 | configFile.output.path =configFile.output.path? configFile.output.path:path.resolve(configFile.context,'dist'); 14 | configFile.watch = true; 15 | 16 | Promise.resolve({then:(resolve,reject)=>{ 17 | resolve(exec(`rm -rf ${configFile.output.path}`)) 18 | }}).then(()=>{ 19 | webpack(configFile,function(err,stats){ 20 | // https://webpack.js.org/configuration/stats/#stats 21 | console.log(stats.toString({ 22 | chunks:true, 23 | assets:true, 24 | children:true, 25 | colors:true, 26 | warnings: true 27 | 28 | })) 29 | }); 30 | }).catch(error=>{ 31 | console.error(error); 32 | process.exit(1) 33 | }) -------------------------------------------------------------------------------- /doc/readme.md: -------------------------------------------------------------------------------- 1 | ## webpack 2 | 1. overview 3 | - modules 输入 4 | 在webpack看来 5 | png jpg 6 | scss less 【css预处理语句】 7 | js 8 | jsx 9 | ts 10 | coffee都是资源 11 | 12 | 13 | ===== webpack来转换这个过程 ==== 14 | scss ==> css ? 15 | 拿到scss的字符串 16 | loader 处理成scss文件 17 | 导出css 18 | 19 | loader : function(content) { return newContent} 20 | plugin : 在是贯穿webppack所有的编译体系里面,异步处理。 21 | 22 | webpack是一个Node.js的运行时(runtime),大量异步过程。 23 | pub/sub, callback 24 | 25 | 配置文件 26 | webpack.config.js 27 | { 28 | entry: {}, // 输入 29 | output: { //输出 30 | path: string, //输出目录 31 | filename: string //文件名 32 | }, 33 | module: { 34 | rules: { 35 | test: /.jsx?$/, 36 | loader: 'babel-loader', 37 | } 38 | }, 39 | plugins: [ 40 | new uglifyJsPlugin() 41 | ==> mangle skrew 42 | 在webpack编译完所有的代码后再压缩和混淆呗? 43 | lifecycle 44 | on('done?',() => { 45 | uglifyJsPlugin 46 | }) 47 | ] 48 | } 49 | 核心: core === 50 | 输入、输入: entry + output 51 | 预处理文件: loader 52 | 编译生命周期: plugins 53 | 54 | 55 | pub/sub: 设计模式 订阅发布 56 | 例子: 57 | $('.a').on('click', callback); 58 | $('.a').trigger('click') ==> callback会触发执行 59 | 60 | 61 | 62 | 63 | 64 | - assets 输出 65 | css 66 | js 67 | html 68 | png 69 | jpg 70 | font等等 71 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack2-tutorial", 3 | "version": "1.0.0", 4 | "description": "a collection of simple demos of Webpack2", 5 | "main": "index.js", 6 | "keywords": [ 7 | "build", 8 | "tutorial", 9 | "webpack2" 10 | ], 11 | "scripts": { 12 | "entry": "node ./command.js -f=entry", 13 | "output": "node ./command.js -f=output", 14 | "split": "node ./command.js -f=code_split", 15 | "module": "node ./command.js -f=modules", 16 | "resolve": "node ./command.js -f=resolve", 17 | "devtool": "node ./command.js -f=devtool", 18 | "loaders": "node ./command.js -f=loaders", 19 | "plugins": "node ./command.js -f=plugins", 20 | "hoist": "node ./command.js -f=scope-hoisting", 21 | "require": "node ./command.js -f=require", 22 | "write": "webpack" 23 | }, 24 | "author": "slashhuang", 25 | "license": "MIT", 26 | "dependencies": { 27 | "babel-core": "^6.13.2", 28 | "babel-loader": "^6.2.4", 29 | "babel-plugin-add-module-exports": "^0.2.1", 30 | "babel-plugin-transform-es3-member-expression-literals": "^6.8.0", 31 | "babel-plugin-transform-es3-property-literals": "^6.8.0", 32 | "babel-plugin-transform-object-assign": "^6.8.0", 33 | "babel-polyfill": "^6.13.0", 34 | "babel-preset-es2015": "^6.13.2", 35 | "babel-preset-react": "^6.11.1", 36 | "babel-preset-stage-0": "^6.5.0", 37 | "babel-register": "^6.24.0", 38 | "copy-webpack-plugin": "^3.0.1", 39 | "css-loader": "^0.27.3", 40 | "extend": "^3.0.0", 41 | "extract-text-webpack-plugin": "^2.1.0", 42 | "file-loader": "~0.8.4", 43 | "html-loader": "^0.4.0", 44 | "less": "^2.7.2", 45 | "less-loader": "^2.2.1", 46 | "sass-loader": "^3.1.2", 47 | "style-loader": "~0.12.3", 48 | "url-loader": "~0.5.6", 49 | "webpack": "^2.3.3", 50 | "webpack-notifier": "^1.3.0" 51 | }, 52 | "repository": "slashhuang/webpack2-tutorial", 53 | "devDependencies": { 54 | "core-js": "^2.4.1", 55 | "yargs": "^7.0.2" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /scope-hoisting/js/0.output.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([0],[ 2 | /* 0 */, 3 | /* 1 */, 4 | /* 2 */ 5 | /*!*****************************!*\ 6 | !*** ./node_modules/cjs.js ***! 7 | \*****************************/ 8 | /*! no static exports found */ 9 | /*! exports used: c */ 10 | /***/ (function(module, exports) { 11 | 12 | // module cjs (commonjs) 13 | exports.c = "e"; 14 | 15 | 16 | /***/ }), 17 | /* 3 */ 18 | /*!*****************************!*\ 19 | !*** ./lazy.js + 2 modules ***! 20 | \*****************************/ 21 | /*! exports provided: d, c, x, y */ 22 | /*! all exports used */ 23 | /*! ModuleConcatenation (inner): module is used with non-harmony imports from ./example.js */ 24 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 25 | 26 | "use strict"; 27 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 28 | 29 | // CONCATENATED MODULE: ./node_modules/c.js 30 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_cjs__ = __webpack_require__(/*! cjs */ 2); 31 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_cjs___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_cjs__); 32 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_shared__ = __webpack_require__(/*! shared */ 0); 33 | // module c 34 | 35 | 36 | var c = String.fromCharCode(__WEBPACK_IMPORTED_MODULE_0_cjs__["c"].charCodeAt(0) - 2); 37 | 38 | 39 | 40 | // CONCATENATED MODULE: ./node_modules/d.js 41 | var d_namespaceObject = {}; 42 | __webpack_require__.d(d_namespaceObject, "a", function() { return a; }); 43 | // module d 44 | var a = "d"; 45 | 46 | // CONCATENATED MODULE: ./lazy.js 47 | /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "c", function() { return c; }); 48 | /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "x", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["a"]; }); 49 | /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "y", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["b"]; }); 50 | /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "d", function() { return d_namespaceObject; }); 51 | 52 | 53 | 54 | 55 | 56 | /***/ }) 57 | ]); -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 2 | var webpack = require("webpack"); 3 | var DefinePlugin = require('webpack/lib/DefinePlugin'); 4 | module.exports = { 5 | context:process.cwd(), //确定了webpack的编译上下文 6 | watch: true, //文件在改变的时候,让webpack动态的更新 7 | // entry: './index.js', // ==> context ==> './index.js' 8 | entry:{ 9 | 'hello':'./hello.js' 10 | }, 11 | 12 | devtool: 'source-map',//资源映射表 chrome debug==> 13 | 14 | output: { 15 | path: path.resolve(process.cwd(),'dist/'), //导出目录 16 | filename: '[name].js' //导出文件的文件名 17 | }, 18 | // alias 别名 require('jquery') 19 | resolve: { 20 | alias:{ jquery: process.cwd()+'/src/lib/jquery.js', } 21 | }, 22 | // 插件 稍后讲 23 | plugins: [ 24 | new webpack.ProvidePlugin({ 25 | $: 'jquery', 26 | _: 'underscore', 27 | React: 'react' 28 | }), 29 | new DefinePlugin({ 30 | 'process.env': { 31 | 'NODE_ENV': JSON.stringify('development') 32 | } 33 | }) 34 | ], 35 | // webpack的对module处理的核心 36 | module: { 37 | //加载方式 38 | loaders: [{ 39 | test: /\.js[x]?$/, //==> 正则表达式 .js .jsx 40 | exclude: /node_modules/, // ==> 排除在loader的范围 41 | loader: 'babel-loader' //加载器,用来处理相关文件 .js index.jsx ==> string =loader=> 我要的另一种形式 42 | // ES6/7 ==> ES5 [一种代码形式 ==> 另一种代码形式] less/sass ==> css 43 | }, { 44 | test: /\.less$/, 45 | loaders:['style-loader', 'css-loader','less-loader'] 46 | // loaders数组 ==等价于== loader:"less!css!style" 47 | // typeof loader=='string' ==> loader.split('!'); 48 | }, { 49 | test: /\.(png|jpg|gif|woff|woff2|ttf|eot|svg|swf)$/, 50 | loader: "file-loader?name=[name]_[sha512:hash:base64:7].[ext]" 51 | }, { 52 | test: /\.html/, 53 | loader: "html-loader?" + JSON.stringify({minimize: false }) 54 | } ] 55 | } 56 | }; -------------------------------------------------------------------------------- /scope-hoisting/template.md: -------------------------------------------------------------------------------- 1 | This example demonstrates Scope Hoisting in combination with Code Splitting. 2 | 3 | This is the dependency graph for the example: (solid lines express sync imports, dashed lines async imports) 4 | 5 | ![](graph.png) 6 | 7 | All modules except `cjs` are EcmaScript modules. `cjs` is a CommonJs module. 8 | 9 | The interesting thing here is that putting all modules in single scope won't work, because of multiple reasons: 10 | 11 | * Modules `lazy`, `c`, `d` and `cjs` need to be in a separate chunk 12 | * Module `shared` is accessed by two chunks (different scopes) 13 | * Module `cjs` is a CommonJs module 14 | 15 | ![](graph2.png) 16 | 17 | webpack therefore uses a approach called **"Partial Scope Hoisting"** or "Module concatenation", which chooses the largest possible subsets of ES modules which can be scope hoisted and combines them with the default webpack primitives. 18 | 19 | ![](graph3.png) 20 | 21 | While module concatentation identifiers in modules are renamed to avoid conflicts and internal imports are simplified. External imports and exports from the root module use the existing ESM constructs. 22 | 23 | # example.js 24 | 25 | ``` javascript 26 | {{example.js}} 27 | ``` 28 | 29 | # lazy.js 30 | 31 | ``` javascript 32 | {{lazy.js}} 33 | ``` 34 | 35 | # a.js 36 | 37 | ``` javascript 38 | {{node_modules/a.js}} 39 | ``` 40 | 41 | # b.js 42 | 43 | ``` javascript 44 | {{node_modules/b.js}} 45 | ``` 46 | 47 | # c.js 48 | 49 | ``` javascript 50 | {{node_modules/c.js}} 51 | ``` 52 | 53 | # d.js 54 | 55 | ``` javascript 56 | {{node_modules/d.js}} 57 | ``` 58 | 59 | # cjs.js 60 | 61 | ``` javascript 62 | {{node_modules/cjs.js}} 63 | ``` 64 | 65 | # shared.js 66 | 67 | ``` javascript 68 | {{node_modules/shared.js}} 69 | ``` 70 | 71 | # shared2.js 72 | 73 | ``` javascript 74 | {{node_modules/shared2.js}} 75 | ``` 76 | 77 | 78 | 79 | # webpack.config.js 80 | 81 | ``` javascript 82 | {{webpack.config.js}} 83 | ``` 84 | 85 | 86 | 87 | 88 | # js/output.js 89 | 90 | ``` javascript 91 | {{js/output.js}} 92 | ``` 93 | 94 | # js/0.output.js 95 | 96 | ``` javascript 97 | {{js/0.output.js}} 98 | ``` 99 | 100 | Minimized 101 | 102 | ``` javascript 103 | {{min:js/0.output.js}} 104 | ``` 105 | 106 | # Info 107 | 108 | ## Uncompressed 109 | 110 | ``` 111 | {{stdout}} 112 | ``` 113 | 114 | ## Minimized (uglify-js, no zip) 115 | 116 | ``` 117 | {{min:stdout}} 118 | ``` 119 | -------------------------------------------------------------------------------- /loaders/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | const path = require('path'), 3 | webpack = require("webpack"), 4 | CopyWebpackPlugin = require('copy-webpack-plugin'), 5 | ExtractTextPlugin = require("extract-text-webpack-plugin"), 6 | WebpackNotifierPlugin = require('webpack-notifier'); 7 | 8 | 9 | let base = { 10 | index:'./index.js', 11 | }; 12 | 13 | module.exports = { 14 | // https://webpack.js.org/configuration/devtool/#devtool 15 | devtool:'source-map', 16 | // https://webpack.js.org/configuration/target/#target 17 | target:"web", 18 | entry:base, 19 | output: { 20 | path: path.resolve(__dirname, 'dist'), 21 | filename: '[name].js' 22 | }, 23 | resolve:{ 24 | alias:{ 25 | test:path.resolve(__dirname,'test/test.js') 26 | } 27 | }, 28 | plugins:[ 29 | new ExtractTextPlugin({ 30 | filename: "[name].css", 31 | disable: false, 32 | allChunks: true 33 | }) 34 | ], 35 | module:{ 36 | //entry => loaders ==> webpack ==> output 37 | rules:[ 38 | { 39 | test: /\.js[x]?$/, 40 | exclude: /node_modules/, 41 | use: { 42 | loader:'babel-loader' 43 | } 44 | }, 45 | { 46 | test: /\.css$/, 47 | use: ExtractTextPlugin.extract({ 48 | fallback: "style-loader", 49 | use:{ 50 | loader:'css-loader', 51 | options: { 52 | sourceMap: true 53 | } 54 | } 55 | }) 56 | }, 57 | { 58 | test: /\.less$/, 59 | use: ExtractTextPlugin.extract({ 60 | fallback:'style-loader', 61 | use:['css-loader',{ 62 | loader:'less-loader', 63 | options: { 64 | sourceMap: true 65 | } 66 | }] 67 | }) 68 | }, 69 | { 70 | test: /\.scss$/, 71 | use: ExtractTextPlugin.extract({ 72 | fallback:'style-loader', 73 | use:['css-loader',{ 74 | loader:'sass-loader', 75 | options: { 76 | sourceMap: true 77 | } 78 | }] 79 | }) 80 | }, 81 | { 82 | test: /\.(png|jpg|jpeg|gif|woff|woff2|ttf|eot|svg|swf)$/, 83 | use: { 84 | loader:'file-loader', 85 | options:{ 86 | name:'[name]_[sha512:hash:base64:7].[ext]' 87 | } 88 | } 89 | }, 90 | { 91 | test: /\.html/, 92 | use:{ 93 | loader:"html-loader", 94 | options:{ 95 | minimize: false, 96 | attrs:false 97 | } 98 | } 99 | } 100 | ] 101 | } 102 | }; 103 | -------------------------------------------------------------------------------- /output/uuudist/_index10c1.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(); 4 | else if(typeof define === 'function' && define.amd) 5 | define([], factory); 6 | else if(typeof exports === 'object') 7 | exports["MyLibrary"] = factory(); 8 | else 9 | root["MyLibrary"] = factory(); 10 | })(this, function() { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | /******/ 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | /******/ 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) { 20 | /******/ return installedModules[moduleId].exports; 21 | /******/ } 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ i: moduleId, 25 | /******/ l: false, 26 | /******/ exports: {} 27 | /******/ }; 28 | /******/ 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | /******/ 32 | /******/ // Flag the module as loaded 33 | /******/ module.l = true; 34 | /******/ 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | /******/ 39 | /******/ 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | /******/ 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | /******/ 46 | /******/ // identity function for calling harmony imports with the correct context 47 | /******/ __webpack_require__.i = function(value) { return value; }; 48 | /******/ 49 | /******/ // define getter function for harmony exports 50 | /******/ __webpack_require__.d = function(exports, name, getter) { 51 | /******/ if(!__webpack_require__.o(exports, name)) { 52 | /******/ Object.defineProperty(exports, name, { 53 | /******/ configurable: false, 54 | /******/ enumerable: true, 55 | /******/ get: getter 56 | /******/ }); 57 | /******/ } 58 | /******/ }; 59 | /******/ 60 | /******/ // getDefaultExport function for compatibility with non-harmony modules 61 | /******/ __webpack_require__.n = function(module) { 62 | /******/ var getter = module && module.__esModule ? 63 | /******/ function getDefault() { return module['default']; } : 64 | /******/ function getModuleExports() { return module; }; 65 | /******/ __webpack_require__.d(getter, 'a', getter); 66 | /******/ return getter; 67 | /******/ }; 68 | /******/ 69 | /******/ // Object.prototype.hasOwnProperty.call 70 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 71 | /******/ 72 | /******/ // __webpack_public_path__ 73 | /******/ __webpack_require__.p = "/output/uuudist/"; 74 | /******/ 75 | /******/ // Load entry module and return exports 76 | /******/ return __webpack_require__(__webpack_require__.s = 0); 77 | /******/ }) 78 | /************************************************************************/ 79 | /******/ ([ 80 | /* 0 */ 81 | /***/ (function(module, exports) { 82 | 83 | console.log('index54245234451.js'); 84 | 85 | module.exports =1 86 | 87 | /***/ }) 88 | /******/ ]); 89 | }); -------------------------------------------------------------------------------- /plugins/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | const path = require('path'), 3 | webpack = require("webpack"), 4 | CopyWebpackPlugin = require('copy-webpack-plugin'), 5 | ExtractTextPlugin = require("extract-text-webpack-plugin"), 6 | WebpackNotifierPlugin = require('webpack-notifier'); 7 | 8 | 9 | let base = { 10 | index:'./index.js', 11 | common:"./common.js" 12 | }; 13 | 14 | module.exports = { 15 | // https://webpack.js.org/configuration/devtool/#devtool 16 | devtool:'source-map', 17 | // https://webpack.js.org/configuration/target/#target 18 | target:"web", 19 | entry:base, 20 | output: { 21 | path: path.resolve(__dirname, 'dist'), 22 | filename: '[name].js' 23 | }, 24 | resolve:{ 25 | alias:{ 26 | test:path.resolve(__dirname,'test/test.js') 27 | } 28 | }, 29 | // webpack lifecycle :before-complitaion run done => 30 | plugins:[ 31 | new webpack.ProvidePlugin({ 32 | $: 'jquery' 33 | }), 34 | new WebpackNotifierPlugin({ 35 | title: 'Webpack 编译成功', 36 | contentImage: path.resolve(process.cwd(), './img/avatar.jpeg'), 37 | alwaysNotify: true 38 | }), 39 | new ExtractTextPlugin({ 40 | filename: "[name].css", 41 | disable: false, 42 | allChunks: true 43 | }), 44 | new webpack.optimize.CommonsChunkPlugin({ 45 | name: 'common', 46 | minChunks: Infinity 47 | }) 48 | ], 49 | module:{ 50 | rules:[ 51 | { 52 | test: /\.js[x]?$/, 53 | exclude: /node_modules/, 54 | use: 'babel-loader' 55 | }, 56 | { 57 | test: /\.css$/, 58 | use: ExtractTextPlugin.extract({ 59 | fallback: "style-loader", 60 | use:{ 61 | loader:'css-loader', 62 | options: { 63 | sourceMap: true 64 | } 65 | } 66 | }) 67 | }, 68 | { 69 | test: /\.less$/, 70 | use: ExtractTextPlugin.extract({ 71 | fallback:'style-loader', 72 | use:['css-loader',{ 73 | loader:'less-loader', 74 | options: { 75 | sourceMap: true 76 | } 77 | }] 78 | }) 79 | }, 80 | { 81 | test: /\.scss$/, 82 | use: ExtractTextPlugin.extract({ 83 | fallback:'style-loader', 84 | use:['css-loader',{ 85 | loader:'sass-loader', 86 | options: { 87 | sourceMap: true 88 | } 89 | }] 90 | }) 91 | }, 92 | { 93 | test: /\.(png|jpg|jpeg|gif|woff|woff2|ttf|eot|svg|swf)$/, 94 | use: { 95 | loader:'file-loader', 96 | options:{ 97 | name:'[name]_[sha512:hash:base64:7].[ext]' 98 | } 99 | } 100 | }, 101 | { 102 | test: /\.html/, 103 | use:{ 104 | loader:"html-loader", 105 | options:{ 106 | minimize: false, 107 | attrs:false 108 | } 109 | } 110 | } 111 | ] 112 | } 113 | }; 114 | -------------------------------------------------------------------------------- /code_split/dist/index.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(); 4 | else if(typeof define === 'function' && define.amd) 5 | define([], factory); 6 | else if(typeof exports === 'object') 7 | exports["MyLibrary"] = factory(); 8 | else 9 | root["MyLibrary"] = factory(); 10 | })(this, function() { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | /******/ 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | /******/ 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) { 20 | /******/ return installedModules[moduleId].exports; 21 | /******/ } 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ i: moduleId, 25 | /******/ l: false, 26 | /******/ exports: {} 27 | /******/ }; 28 | /******/ 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | /******/ 32 | /******/ // Flag the module as loaded 33 | /******/ module.l = true; 34 | /******/ 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | /******/ 39 | /******/ 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | /******/ 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | /******/ 46 | /******/ // identity function for calling harmony imports with the correct context 47 | /******/ __webpack_require__.i = function(value) { return value; }; 48 | /******/ 49 | /******/ // define getter function for harmony exports 50 | /******/ __webpack_require__.d = function(exports, name, getter) { 51 | /******/ if(!__webpack_require__.o(exports, name)) { 52 | /******/ Object.defineProperty(exports, name, { 53 | /******/ configurable: false, 54 | /******/ enumerable: true, 55 | /******/ get: getter 56 | /******/ }); 57 | /******/ } 58 | /******/ }; 59 | /******/ 60 | /******/ // getDefaultExport function for compatibility with non-harmony modules 61 | /******/ __webpack_require__.n = function(module) { 62 | /******/ var getter = module && module.__esModule ? 63 | /******/ function getDefault() { return module['default']; } : 64 | /******/ function getModuleExports() { return module; }; 65 | /******/ __webpack_require__.d(getter, 'a', getter); 66 | /******/ return getter; 67 | /******/ }; 68 | /******/ 69 | /******/ // Object.prototype.hasOwnProperty.call 70 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 71 | /******/ 72 | /******/ // __webpack_public_path__ 73 | /******/ __webpack_require__.p = "/dist/"; 74 | /******/ 75 | /******/ // Load entry module and return exports 76 | /******/ return __webpack_require__(__webpack_require__.s = 1); 77 | /******/ }) 78 | /************************************************************************/ 79 | /******/ ([ 80 | /* 0 */ 81 | /***/ (function(module, exports) { 82 | 83 | console.log('I am a split') 84 | 85 | /***/ }), 86 | /* 1 */ 87 | /***/ (function(module, exports, __webpack_require__) { 88 | 89 | // export import 90 | // amd 91 | // require 92 | 93 | console.log('I am index') 94 | 95 | // require.ensure(dependencies: String[], callback: function(require), chunkName: String) 96 | 97 | __webpack_require__(0); 98 | // import * as Test from './split.js'; 99 | 100 | /***/ }) 101 | /******/ ]); 102 | }); -------------------------------------------------------------------------------- /scope-hoisting/graph.svg: -------------------------------------------------------------------------------- 1 | exampleabsharedshared2lazycdcjs -------------------------------------------------------------------------------- /demo.webpack.config.js: -------------------------------------------------------------------------------- 1 | //官方最终版 2 | 3 | 4 | const path = require('path'); 5 | 6 | module.exports = { 7 | // click on the name of the option to get to the detailed documentation 8 | // click on the items with arrows to show more examples / advanced options 9 | 10 | entry: "./app/entry", // string | object | array 11 | // Here the application starts executing 12 | // and webpack starts bundling 13 | 14 | output: { 15 | // options related to how webpack emits results 16 | 17 | path: path.resolve(__dirname, "dist"), // string 18 | // the target directory for all output files 19 | // must be an absolute path (use the Node.js path module) 20 | 21 | filename: "bundle.js", // string 22 | // the filename template for entry chunks 23 | 24 | publicPath: "/assets/", // string 25 | // the url to the output directory resolved relative to the HTML page 26 | 27 | library: "MyLibrary", // string, 28 | // the name of the exported library 29 | 30 | libraryTarget: "umd", // universal module definition 31 | // the type of the exported library 32 | 33 | /* Advanced output configuration (click to show) */ 34 | }, 35 | 36 | module: { 37 | // configuration regarding modules 38 | 39 | rules: [ 40 | // rules for modules (configure loaders, parser options, etc.) 41 | 42 | { 43 | test: /\.jsx?$/, 44 | include: [ 45 | path.resolve(__dirname, "app") 46 | ], 47 | exclude: [ 48 | path.resolve(__dirname, "app/demo-files") 49 | ], 50 | // these are matching conditions, each accepting a regular expression or string 51 | // test and include have the same behavior, both must be matched 52 | // exclude must not be matched (takes preferrence over test and include) 53 | // Best practices: 54 | // - Use RegExp only in test and for filename matching 55 | // - Use arrays of absolute paths in include and exclude 56 | // - Try to avoid exclude and prefer include 57 | 58 | issuer: { test, include, exclude }, 59 | // conditions for the issuer (the origin of the import) 60 | 61 | enforce: "pre", 62 | enforce: "post", 63 | // flags to apply these rules, even if they are overridden (advanced option) 64 | 65 | loader: "babel-loader", 66 | // the loader which should be applied, it'll be resolved relative to the context 67 | // -loader suffix is no longer optional in webpack2 for clarity reasons 68 | // see webpack 1 upgrade guide 69 | 70 | options: { 71 | presets: ["es2015"] 72 | }, 73 | // options for the loader 74 | }, 75 | 76 | { 77 | test: "\.html$", 78 | 79 | use: [ 80 | // apply multiple loaders and options 81 | "htmllint-loader", 82 | { 83 | loader: "html-loader", 84 | options: { 85 | /* ... */ 86 | } 87 | } 88 | ] 89 | }, 90 | 91 | { oneOf: [ /* rules */ ] }, 92 | // only use one of these nested rules 93 | 94 | { rules: [ /* rules */ ] }, 95 | // use all of these nested rules (combine with conditions to be useful) 96 | 97 | { resource: { and: [ /* conditions */ ] } }, 98 | // matches only if all conditions are matched 99 | 100 | { resource: { or: [ /* conditions */ ] } }, 101 | { resource: [ /* conditions */ ] }, 102 | // matches if any condition is matched (default for arrays) 103 | 104 | { resource: { not: /* condition */ } } 105 | // matches if the condition is not matched 106 | ], 107 | 108 | /* Advanced module configuration (click to show) */ 109 | }, 110 | 111 | resolve: { 112 | // options for resolving module requests 113 | // (does not apply to resolving to loaders) 114 | 115 | modules: [ 116 | "node_modules", 117 | path.resolve(__dirname, "app") 118 | ], 119 | // directories where to look for modules 120 | 121 | extensions: [".js", ".json", ".jsx", ".css"], 122 | // extensions that are used 123 | 124 | alias: { 125 | // a list of module name aliases 126 | 127 | "module": "new-module", 128 | // alias "module" -> "new-module" and "module/path/file" -> "new-module/path/file" 129 | 130 | "only-module$": "new-module", 131 | // alias "only-module" -> "new-module", but not "module/path/file" -> "new-module/path/file" 132 | 133 | "module": path.resolve(__dirname, "app/third/module.js"), 134 | // alias "module" -> "./app/third/module.js" and "module/file" results in error 135 | // modules aliases are imported relative to the current context 136 | }, 137 | /* alternative alias syntax (click to show) */ 138 | 139 | /* Advanced resolve configuration (click to show) */ 140 | }, 141 | 142 | performance: { 143 | hints: "warning", // enum 144 | maxAssetSize: 200000, // int (in bytes), 145 | maxEntrypointSize: 400000, // int (in bytes) 146 | assetFilter: function(assetFilename) { 147 | // Function predicate that provides asset filenames 148 | return assetFilename.endsWith('.css') || assetFilename.endsWith('.js'); 149 | } 150 | }, 151 | 152 | devtool: "source-map", // enum 153 | // enhance debugging by adding meta info for the browser devtools 154 | // source-map most detailed at the expense of build speed. 155 | 156 | context: __dirname, // string (absolute path!) 157 | // the home directory for webpack 158 | // the entry and module.rules.loader option 159 | // is resolved relative to this directory 160 | 161 | target: "web", // enum 162 | // the environment in which the bundle should run 163 | // changes chunk loading behavior and available modules 164 | 165 | externals: ["react", /^@angular\//], 166 | // Don't follow/bundle these modules, but request them at runtime from the environment 167 | 168 | stats: "errors-only", 169 | // lets you precisely control what bundle information gets displayed 170 | 171 | devServer: { 172 | proxy: { // proxy URLs to backend development server 173 | '/api': 'http://localhost:3000' 174 | }, 175 | contentBase: path.join(__dirname, 'public'), // boolean | string | array, static file location 176 | compress: true, // enable gzip compression 177 | historyApiFallback: true, // true for index.html upon 404, object for multiple paths 178 | hot: true, // hot module replacement. Depends on HotModuleReplacementPlugin 179 | https: false, // true for self-signed, object for cert authority 180 | noInfo: true, // only errors & warns on hot reload 181 | // ... 182 | }, 183 | 184 | plugins: [ 185 | // ... 186 | ], 187 | // list of additional plugins 188 | 189 | 190 | /* Advanced configuration (click to show) */ 191 | } -------------------------------------------------------------------------------- /output/uuudist/_index16f.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(); 4 | else if(typeof define === 'function' && define.amd) 5 | define([], factory); 6 | else if(typeof exports === 'object') 7 | exports["MyLibrary"] = factory(); 8 | else 9 | root["MyLibrary"] = factory(); 10 | })(this, function() { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // install a JSONP callback for chunk loading 13 | /******/ var parentJsonpFunction = window["webpackJsonpMyLibrary"]; 14 | /******/ window["webpackJsonpMyLibrary"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) { 15 | /******/ // add "moreModules" to the modules object, 16 | /******/ // then flag all "chunkIds" as loaded and fire callback 17 | /******/ var moduleId, chunkId, i = 0, resolves = [], result; 18 | /******/ for(;i < chunkIds.length; i++) { 19 | /******/ chunkId = chunkIds[i]; 20 | /******/ if(installedChunks[chunkId]) { 21 | /******/ resolves.push(installedChunks[chunkId][0]); 22 | /******/ } 23 | /******/ installedChunks[chunkId] = 0; 24 | /******/ } 25 | /******/ for(moduleId in moreModules) { 26 | /******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { 27 | /******/ modules[moduleId] = moreModules[moduleId]; 28 | /******/ } 29 | /******/ } 30 | /******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules); 31 | /******/ while(resolves.length) { 32 | /******/ resolves.shift()(); 33 | /******/ } 34 | /******/ 35 | /******/ }; 36 | /******/ 37 | /******/ // The module cache 38 | /******/ var installedModules = {}; 39 | /******/ 40 | /******/ // objects to store loaded and loading chunks 41 | /******/ var installedChunks = { 42 | /******/ 2: 0 43 | /******/ }; 44 | /******/ 45 | /******/ // The require function 46 | /******/ function __webpack_require__(moduleId) { 47 | /******/ 48 | /******/ // Check if module is in cache 49 | /******/ if(installedModules[moduleId]) { 50 | /******/ return installedModules[moduleId].exports; 51 | /******/ } 52 | /******/ // Create a new module (and put it into the cache) 53 | /******/ var module = installedModules[moduleId] = { 54 | /******/ i: moduleId, 55 | /******/ l: false, 56 | /******/ exports: {} 57 | /******/ }; 58 | /******/ 59 | /******/ // Execute the module function 60 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 61 | /******/ 62 | /******/ // Flag the module as loaded 63 | /******/ module.l = true; 64 | /******/ 65 | /******/ // Return the exports of the module 66 | /******/ return module.exports; 67 | /******/ } 68 | /******/ 69 | /******/ // This file contains only the entry chunk. 70 | /******/ // The chunk loading function for additional chunks 71 | /******/ __webpack_require__.e = function requireEnsure(chunkId) { 72 | /******/ var installedChunkData = installedChunks[chunkId]; 73 | /******/ if(installedChunkData === 0) { 74 | /******/ return new Promise(function(resolve) { resolve(); }); 75 | /******/ } 76 | /******/ 77 | /******/ // a Promise means "currently loading". 78 | /******/ if(installedChunkData) { 79 | /******/ return installedChunkData[2]; 80 | /******/ } 81 | /******/ 82 | /******/ // setup Promise in chunk cache 83 | /******/ var promise = new Promise(function(resolve, reject) { 84 | /******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; 85 | /******/ }); 86 | /******/ installedChunkData[2] = promise; 87 | /******/ 88 | /******/ // start chunk loading 89 | /******/ var head = document.getElementsByTagName('head')[0]; 90 | /******/ var script = document.createElement('script'); 91 | /******/ script.type = 'text/javascript'; 92 | /******/ script.charset = 'utf-8'; 93 | /******/ script.async = true; 94 | /******/ script.timeout = 120000; 95 | /******/ 96 | /******/ if (__webpack_require__.nc) { 97 | /******/ script.setAttribute("nonce", __webpack_require__.nc); 98 | /******/ } 99 | /******/ script.src = __webpack_require__.p + "" + {"0":"5df"}[chunkId] + "_" + ({"0":"dynamic"}[chunkId]||chunkId) + ".js"; 100 | /******/ var timeout = setTimeout(onScriptComplete, 120000); 101 | /******/ script.onerror = script.onload = onScriptComplete; 102 | /******/ function onScriptComplete() { 103 | /******/ // avoid mem leaks in IE. 104 | /******/ script.onerror = script.onload = null; 105 | /******/ clearTimeout(timeout); 106 | /******/ var chunk = installedChunks[chunkId]; 107 | /******/ if(chunk !== 0) { 108 | /******/ if(chunk) { 109 | /******/ chunk[1](new Error('Loading chunk ' + chunkId + ' failed.')); 110 | /******/ } 111 | /******/ installedChunks[chunkId] = undefined; 112 | /******/ } 113 | /******/ }; 114 | /******/ head.appendChild(script); 115 | /******/ 116 | /******/ return promise; 117 | /******/ }; 118 | /******/ 119 | /******/ // expose the modules object (__webpack_modules__) 120 | /******/ __webpack_require__.m = modules; 121 | /******/ 122 | /******/ // expose the module cache 123 | /******/ __webpack_require__.c = installedModules; 124 | /******/ 125 | /******/ // identity function for calling harmony imports with the correct context 126 | /******/ __webpack_require__.i = function(value) { return value; }; 127 | /******/ 128 | /******/ // define getter function for harmony exports 129 | /******/ __webpack_require__.d = function(exports, name, getter) { 130 | /******/ if(!__webpack_require__.o(exports, name)) { 131 | /******/ Object.defineProperty(exports, name, { 132 | /******/ configurable: false, 133 | /******/ enumerable: true, 134 | /******/ get: getter 135 | /******/ }); 136 | /******/ } 137 | /******/ }; 138 | /******/ 139 | /******/ // getDefaultExport function for compatibility with non-harmony modules 140 | /******/ __webpack_require__.n = function(module) { 141 | /******/ var getter = module && module.__esModule ? 142 | /******/ function getDefault() { return module['default']; } : 143 | /******/ function getModuleExports() { return module; }; 144 | /******/ __webpack_require__.d(getter, 'a', getter); 145 | /******/ return getter; 146 | /******/ }; 147 | /******/ 148 | /******/ // Object.prototype.hasOwnProperty.call 149 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 150 | /******/ 151 | /******/ // __webpack_public_path__ 152 | /******/ __webpack_require__.p = "/output/uuudist/"; 153 | /******/ 154 | /******/ // on error function for async loading 155 | /******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; 156 | /******/ 157 | /******/ // Load entry module and return exports 158 | /******/ return __webpack_require__(__webpack_require__.s = 1); 159 | /******/ }) 160 | /************************************************************************/ 161 | /******/ ([ 162 | /* 0 */, 163 | /* 1 */ 164 | /***/ (function(module, exports, __webpack_require__) { 165 | 166 | console.log('I am index') 167 | 168 | //require.ensure(dependencies: String[], callback: function(require), chunkName: String) 169 | 170 | //异步加载 171 | __webpack_require__.e/* require.ensure */(0).then(((require)=>{ 172 | __webpack_require__(0) 173 | }).bind(null, __webpack_require__)).catch(__webpack_require__.oe) 174 | 175 | /***/ }) 176 | /******/ ]); 177 | }); -------------------------------------------------------------------------------- /scope-hoisting/graph2.svg: -------------------------------------------------------------------------------- 1 | Chunk AChunk Bexampleabsharedshared2lazycdcjs -------------------------------------------------------------------------------- /scope-hoisting/js/output.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // install a JSONP callback for chunk loading 3 | /******/ var parentJsonpFunction = window["webpackJsonp"]; 4 | /******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) { 5 | /******/ // add "moreModules" to the modules object, 6 | /******/ // then flag all "chunkIds" as loaded and fire callback 7 | /******/ var moduleId, chunkId, i = 0, resolves = [], result; 8 | /******/ for(;i < chunkIds.length; i++) { 9 | /******/ chunkId = chunkIds[i]; 10 | /******/ if(installedChunks[chunkId]) { 11 | /******/ resolves.push(installedChunks[chunkId][0]); 12 | /******/ } 13 | /******/ installedChunks[chunkId] = 0; 14 | /******/ } 15 | /******/ for(moduleId in moreModules) { 16 | /******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { 17 | /******/ modules[moduleId] = moreModules[moduleId]; 18 | /******/ } 19 | /******/ } 20 | /******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules); 21 | /******/ while(resolves.length) { 22 | /******/ resolves.shift()(); 23 | /******/ } 24 | /******/ 25 | /******/ }; 26 | /******/ 27 | /******/ // The module cache 28 | /******/ var installedModules = {}; 29 | /******/ 30 | /******/ // objects to store loaded and loading chunks 31 | /******/ var installedChunks = { 32 | /******/ 1: 0 33 | /******/ }; 34 | /******/ 35 | /******/ // The require function 36 | /******/ function __webpack_require__(moduleId) { 37 | /******/ 38 | /******/ // Check if module is in cache 39 | /******/ if(installedModules[moduleId]) { 40 | /******/ return installedModules[moduleId].exports; 41 | /******/ } 42 | /******/ // Create a new module (and put it into the cache) 43 | /******/ var module = installedModules[moduleId] = { 44 | /******/ i: moduleId, 45 | /******/ l: false, 46 | /******/ exports: {} 47 | /******/ }; 48 | /******/ 49 | /******/ // Execute the module function 50 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 51 | /******/ 52 | /******/ // Flag the module as loaded 53 | /******/ module.l = true; 54 | /******/ 55 | /******/ // Return the exports of the module 56 | /******/ return module.exports; 57 | /******/ } 58 | /******/ 59 | /******/ // This file contains only the entry chunk. 60 | /******/ // The chunk loading function for additional chunks 61 | /******/ __webpack_require__.e = function requireEnsure(chunkId) { 62 | /******/ var installedChunkData = installedChunks[chunkId]; 63 | /******/ if(installedChunkData === 0) { 64 | /******/ return new Promise(function(resolve) { resolve(); }); 65 | /******/ } 66 | /******/ 67 | /******/ // a Promise means "currently loading". 68 | /******/ if(installedChunkData) { 69 | /******/ return installedChunkData[2]; 70 | /******/ } 71 | /******/ 72 | /******/ // setup Promise in chunk cache 73 | /******/ var promise = new Promise(function(resolve, reject) { 74 | /******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; 75 | /******/ }); 76 | /******/ installedChunkData[2] = promise; 77 | /******/ 78 | /******/ // start chunk loading 79 | /******/ var head = document.getElementsByTagName('head')[0]; 80 | /******/ var script = document.createElement('script'); 81 | /******/ script.type = 'text/javascript'; 82 | /******/ script.charset = 'utf-8'; 83 | /******/ script.async = true; 84 | /******/ script.timeout = 120000; 85 | /******/ 86 | /******/ if (__webpack_require__.nc) { 87 | /******/ script.setAttribute("nonce", __webpack_require__.nc); 88 | /******/ } 89 | /******/ script.src = __webpack_require__.p + "" + chunkId + ".output.js"; 90 | /******/ var timeout = setTimeout(onScriptComplete, 120000); 91 | /******/ script.onerror = script.onload = onScriptComplete; 92 | /******/ function onScriptComplete() { 93 | /******/ // avoid mem leaks in IE. 94 | /******/ script.onerror = script.onload = null; 95 | /******/ clearTimeout(timeout); 96 | /******/ var chunk = installedChunks[chunkId]; 97 | /******/ if(chunk !== 0) { 98 | /******/ if(chunk) { 99 | /******/ chunk[1](new Error('Loading chunk ' + chunkId + ' failed.')); 100 | /******/ } 101 | /******/ installedChunks[chunkId] = undefined; 102 | /******/ } 103 | /******/ }; 104 | /******/ head.appendChild(script); 105 | /******/ 106 | /******/ return promise; 107 | /******/ }; 108 | /******/ 109 | /******/ // expose the modules object (__webpack_modules__) 110 | /******/ __webpack_require__.m = modules; 111 | /******/ 112 | /******/ // expose the module cache 113 | /******/ __webpack_require__.c = installedModules; 114 | /******/ 115 | /******/ // define getter function for harmony exports 116 | /******/ __webpack_require__.d = function(exports, name, getter) { 117 | /******/ if(!__webpack_require__.o(exports, name)) { 118 | /******/ Object.defineProperty(exports, name, { 119 | /******/ configurable: false, 120 | /******/ enumerable: true, 121 | /******/ get: getter 122 | /******/ }); 123 | /******/ } 124 | /******/ }; 125 | /******/ 126 | /******/ // getDefaultExport function for compatibility with non-harmony modules 127 | /******/ __webpack_require__.n = function(module) { 128 | /******/ var getter = module && module.__esModule ? 129 | /******/ function getDefault() { return module['default']; } : 130 | /******/ function getModuleExports() { return module; }; 131 | /******/ __webpack_require__.d(getter, 'a', getter); 132 | /******/ return getter; 133 | /******/ }; 134 | /******/ 135 | /******/ // Object.prototype.hasOwnProperty.call 136 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 137 | /******/ 138 | /******/ // __webpack_public_path__ 139 | /******/ __webpack_require__.p = "js/"; 140 | /******/ 141 | /******/ // on error function for async loading 142 | /******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; 143 | /******/ 144 | /******/ // Load entry module and return exports 145 | /******/ return __webpack_require__(__webpack_require__.s = 1); 146 | /******/ }) 147 | /************************************************************************/ 148 | /******/ ([ 149 | /* 0 */ 150 | /*!********************************************!*\ 151 | !*** ./node_modules/shared.js + 1 modules ***! 152 | \********************************************/ 153 | /*! exports provided: x, y */ 154 | /*! exports used: x, y */ 155 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 156 | 157 | "use strict"; 158 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 159 | 160 | // CONCATENATED MODULE: ./node_modules/shared2.js 161 | // shared2 module 162 | var y = "y"; 163 | 164 | // CONCATENATED MODULE: ./node_modules/shared.js 165 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return x; }); 166 | /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "b", function() { return y; }); 167 | // shared module 168 | var x = "x"; 169 | 170 | 171 | 172 | /***/ }), 173 | /* 1 */ 174 | /*!********************************!*\ 175 | !*** ./example.js + 2 modules ***! 176 | \********************************/ 177 | /*! exports provided: */ 178 | /*! all exports used */ 179 | /*! ModuleConcatenation (inner): module is an entrypoint */ 180 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 181 | 182 | "use strict"; 183 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 184 | 185 | // CONCATENATED MODULE: ./node_modules/a.js 186 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_shared__ = __webpack_require__(/*! shared */ 0); 187 | // module a 188 | var a = "a"; 189 | 190 | 191 | // CONCATENATED MODULE: ./node_modules/b.js 192 | // module b 193 | function b_a() { 194 | return "b"; 195 | }; 196 | 197 | // CONCATENATED MODULE: ./example.js 198 | 199 | 200 | 201 | __webpack_require__.e/* import() */(0).then(__webpack_require__.bind(null, /*! ./lazy */ 3)).then(function(lazy) { 202 | console.log(a, b_a(), __WEBPACK_IMPORTED_MODULE_0_shared__["a"], __WEBPACK_IMPORTED_MODULE_0_shared__["b"], lazy.c, lazy.d.a, lazy.x, lazy.y); 203 | }); 204 | 205 | 206 | /***/ }) 207 | /******/ ]); -------------------------------------------------------------------------------- /scope-hoisting/graph3.svg: -------------------------------------------------------------------------------- 1 | Chunk AScope 1Scope 2Chunk BScope 3exampleabsharedshared2cjslazycd -------------------------------------------------------------------------------- /scope-hoisting/README.md: -------------------------------------------------------------------------------- 1 | This example demonstrates Scope Hoisting in combination with Code Splitting. 2 | 3 | This is the dependency graph for the example: (solid lines express sync imports, dashed lines async imports) 4 | 5 | ![](graph.png) 6 | 7 | All modules except `cjs` are EcmaScript modules. `cjs` is a CommonJs module. 8 | 9 | The interesting thing here is that putting all modules in single scope won't work, because of multiple reasons: 10 | 11 | * Modules `lazy`, `c`, `d` and `cjs` need to be in a separate chunk 12 | * Module `shared` is accessed by two chunks (different scopes) 13 | * Module `cjs` is a CommonJs module 14 | 15 | ![](graph2.png) 16 | 17 | webpack therefore uses a approach called **"Partial Scope Hoisting"** or "Module concatenation", which chooses the largest possible subsets of ES modules which can be scope hoisted and combines them with the default webpack primitives. 18 | 19 | ![](graph3.png) 20 | 21 | While module concatentation identifiers in modules are renamed to avoid conflicts and internal imports are simplified. External imports and exports from the root module use the existing ESM constructs. 22 | 23 | # example.js 24 | 25 | ``` javascript 26 | import { a, x, y } from "a"; 27 | import * as b from "b"; 28 | 29 | import("./lazy").then(function(lazy) { 30 | console.log(a, b.a(), x, y, lazy.c, lazy.d.a, lazy.x, lazy.y); 31 | }); 32 | ``` 33 | 34 | # lazy.js 35 | 36 | ``` javascript 37 | export * from "c"; 38 | import * as d from "d"; 39 | export { d }; 40 | ``` 41 | 42 | # a.js 43 | 44 | ``` javascript 45 | // module a 46 | export var a = "a"; 47 | export * from "shared"; 48 | ``` 49 | 50 | # b.js 51 | 52 | ``` javascript 53 | // module b 54 | export function a() { 55 | return "b"; 56 | }; 57 | ``` 58 | 59 | # c.js 60 | 61 | ``` javascript 62 | // module c 63 | import { c as e } from "cjs"; 64 | 65 | export var c = String.fromCharCode(e.charCodeAt(0) - 2); 66 | 67 | export { x, y } from "shared"; 68 | ``` 69 | 70 | # d.js 71 | 72 | ``` javascript 73 | // module d 74 | export var a = "d"; 75 | ``` 76 | 77 | # cjs.js 78 | 79 | ``` javascript 80 | // module cjs (commonjs) 81 | exports.c = "e"; 82 | ``` 83 | 84 | # shared.js 85 | 86 | ``` javascript 87 | // shared module 88 | export var x = "x"; 89 | export * from "shared2"; 90 | ``` 91 | 92 | # shared2.js 93 | 94 | ``` javascript 95 | // shared2 module 96 | export var y = "y"; 97 | ``` 98 | 99 | 100 | 101 | # webpack.config.js 102 | 103 | ``` javascript 104 | var webpack = require("../../"); 105 | 106 | module.exports = { 107 | plugins: [ 108 | new webpack.optimize.ModuleConcatenationPlugin() 109 | ] 110 | }; 111 | ``` 112 | 113 | 114 | 115 | 116 | # js/output.js 117 | 118 |
/******/ (function(modules) { /* webpackBootstrap */ }) 119 | 120 | ``` javascript 121 | /******/ (function(modules) { // webpackBootstrap 122 | /******/ // install a JSONP callback for chunk loading 123 | /******/ var parentJsonpFunction = window["webpackJsonp"]; 124 | /******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) { 125 | /******/ // add "moreModules" to the modules object, 126 | /******/ // then flag all "chunkIds" as loaded and fire callback 127 | /******/ var moduleId, chunkId, i = 0, resolves = [], result; 128 | /******/ for(;i < chunkIds.length; i++) { 129 | /******/ chunkId = chunkIds[i]; 130 | /******/ if(installedChunks[chunkId]) { 131 | /******/ resolves.push(installedChunks[chunkId][0]); 132 | /******/ } 133 | /******/ installedChunks[chunkId] = 0; 134 | /******/ } 135 | /******/ for(moduleId in moreModules) { 136 | /******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { 137 | /******/ modules[moduleId] = moreModules[moduleId]; 138 | /******/ } 139 | /******/ } 140 | /******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules); 141 | /******/ while(resolves.length) { 142 | /******/ resolves.shift()(); 143 | /******/ } 144 | /******/ 145 | /******/ }; 146 | /******/ 147 | /******/ // The module cache 148 | /******/ var installedModules = {}; 149 | /******/ 150 | /******/ // objects to store loaded and loading chunks 151 | /******/ var installedChunks = { 152 | /******/ 1: 0 153 | /******/ }; 154 | /******/ 155 | /******/ // The require function 156 | /******/ function __webpack_require__(moduleId) { 157 | /******/ 158 | /******/ // Check if module is in cache 159 | /******/ if(installedModules[moduleId]) { 160 | /******/ return installedModules[moduleId].exports; 161 | /******/ } 162 | /******/ // Create a new module (and put it into the cache) 163 | /******/ var module = installedModules[moduleId] = { 164 | /******/ i: moduleId, 165 | /******/ l: false, 166 | /******/ exports: {} 167 | /******/ }; 168 | /******/ 169 | /******/ // Execute the module function 170 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 171 | /******/ 172 | /******/ // Flag the module as loaded 173 | /******/ module.l = true; 174 | /******/ 175 | /******/ // Return the exports of the module 176 | /******/ return module.exports; 177 | /******/ } 178 | /******/ 179 | /******/ // This file contains only the entry chunk. 180 | /******/ // The chunk loading function for additional chunks 181 | /******/ __webpack_require__.e = function requireEnsure(chunkId) { 182 | /******/ var installedChunkData = installedChunks[chunkId]; 183 | /******/ if(installedChunkData === 0) { 184 | /******/ return new Promise(function(resolve) { resolve(); }); 185 | /******/ } 186 | /******/ 187 | /******/ // a Promise means "currently loading". 188 | /******/ if(installedChunkData) { 189 | /******/ return installedChunkData[2]; 190 | /******/ } 191 | /******/ 192 | /******/ // setup Promise in chunk cache 193 | /******/ var promise = new Promise(function(resolve, reject) { 194 | /******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; 195 | /******/ }); 196 | /******/ installedChunkData[2] = promise; 197 | /******/ 198 | /******/ // start chunk loading 199 | /******/ var head = document.getElementsByTagName('head')[0]; 200 | /******/ var script = document.createElement('script'); 201 | /******/ script.type = 'text/javascript'; 202 | /******/ script.charset = 'utf-8'; 203 | /******/ script.async = true; 204 | /******/ script.timeout = 120000; 205 | /******/ 206 | /******/ if (__webpack_require__.nc) { 207 | /******/ script.setAttribute("nonce", __webpack_require__.nc); 208 | /******/ } 209 | /******/ script.src = __webpack_require__.p + "" + chunkId + ".output.js"; 210 | /******/ var timeout = setTimeout(onScriptComplete, 120000); 211 | /******/ script.onerror = script.onload = onScriptComplete; 212 | /******/ function onScriptComplete() { 213 | /******/ // avoid mem leaks in IE. 214 | /******/ script.onerror = script.onload = null; 215 | /******/ clearTimeout(timeout); 216 | /******/ var chunk = installedChunks[chunkId]; 217 | /******/ if(chunk !== 0) { 218 | /******/ if(chunk) { 219 | /******/ chunk[1](new Error('Loading chunk ' + chunkId + ' failed.')); 220 | /******/ } 221 | /******/ installedChunks[chunkId] = undefined; 222 | /******/ } 223 | /******/ }; 224 | /******/ head.appendChild(script); 225 | /******/ 226 | /******/ return promise; 227 | /******/ }; 228 | /******/ 229 | /******/ // expose the modules object (__webpack_modules__) 230 | /******/ __webpack_require__.m = modules; 231 | /******/ 232 | /******/ // expose the module cache 233 | /******/ __webpack_require__.c = installedModules; 234 | /******/ 235 | /******/ // define getter function for harmony exports 236 | /******/ __webpack_require__.d = function(exports, name, getter) { 237 | /******/ if(!__webpack_require__.o(exports, name)) { 238 | /******/ Object.defineProperty(exports, name, { 239 | /******/ configurable: false, 240 | /******/ enumerable: true, 241 | /******/ get: getter 242 | /******/ }); 243 | /******/ } 244 | /******/ }; 245 | /******/ 246 | /******/ // getDefaultExport function for compatibility with non-harmony modules 247 | /******/ __webpack_require__.n = function(module) { 248 | /******/ var getter = module && module.__esModule ? 249 | /******/ function getDefault() { return module['default']; } : 250 | /******/ function getModuleExports() { return module; }; 251 | /******/ __webpack_require__.d(getter, 'a', getter); 252 | /******/ return getter; 253 | /******/ }; 254 | /******/ 255 | /******/ // Object.prototype.hasOwnProperty.call 256 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 257 | /******/ 258 | /******/ // __webpack_public_path__ 259 | /******/ __webpack_require__.p = "js/"; 260 | /******/ 261 | /******/ // on error function for async loading 262 | /******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; 263 | /******/ 264 | /******/ // Load entry module and return exports 265 | /******/ return __webpack_require__(__webpack_require__.s = 1); 266 | /******/ }) 267 | /************************************************************************/ 268 | ``` 269 | 270 |
271 | 272 | ``` javascript 273 | /******/ ([ 274 | /* 0 */ 275 | /*!********************************************!*\ 276 | !*** ./node_modules/shared.js + 1 modules ***! 277 | \********************************************/ 278 | /*! exports provided: x, y */ 279 | /*! exports used: x, y */ 280 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 281 | 282 | "use strict"; 283 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 284 | 285 | // CONCATENATED MODULE: ./node_modules/shared2.js 286 | // shared2 module 287 | var y = "y"; 288 | 289 | // CONCATENATED MODULE: ./node_modules/shared.js 290 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return x; }); 291 | /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "b", function() { return y; }); 292 | // shared module 293 | var x = "x"; 294 | 295 | 296 | 297 | /***/ }), 298 | /* 1 */ 299 | /*!********************************!*\ 300 | !*** ./example.js + 2 modules ***! 301 | \********************************/ 302 | /*! exports provided: */ 303 | /*! all exports used */ 304 | /*! ModuleConcatenation (inner): module is an entrypoint */ 305 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 306 | 307 | "use strict"; 308 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 309 | 310 | // CONCATENATED MODULE: ./node_modules/a.js 311 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_shared__ = __webpack_require__(/*! shared */ 0); 312 | // module a 313 | var a = "a"; 314 | 315 | 316 | // CONCATENATED MODULE: ./node_modules/b.js 317 | // module b 318 | function b_a() { 319 | return "b"; 320 | }; 321 | 322 | // CONCATENATED MODULE: ./example.js 323 | 324 | 325 | 326 | __webpack_require__.e/* import() */(0).then(__webpack_require__.bind(null, /*! ./lazy */ 3)).then(function(lazy) { 327 | console.log(a, b_a(), __WEBPACK_IMPORTED_MODULE_0_shared__["a"], __WEBPACK_IMPORTED_MODULE_0_shared__["b"], lazy.c, lazy.d.a, lazy.x, lazy.y); 328 | }); 329 | 330 | 331 | /***/ }) 332 | /******/ ]); 333 | ``` 334 | 335 | # js/0.output.js 336 | 337 | ``` javascript 338 | webpackJsonp([0],[ 339 | /* 0 */, 340 | /* 1 */, 341 | /* 2 */ 342 | /*!*****************************!*\ 343 | !*** ./node_modules/cjs.js ***! 344 | \*****************************/ 345 | /*! no static exports found */ 346 | /*! exports used: c */ 347 | /***/ (function(module, exports) { 348 | 349 | // module cjs (commonjs) 350 | exports.c = "e"; 351 | 352 | 353 | /***/ }), 354 | /* 3 */ 355 | /*!*****************************!*\ 356 | !*** ./lazy.js + 2 modules ***! 357 | \*****************************/ 358 | /*! exports provided: d, c, x, y */ 359 | /*! all exports used */ 360 | /*! ModuleConcatenation (inner): module is used with non-harmony imports from ./example.js */ 361 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 362 | 363 | "use strict"; 364 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 365 | 366 | // CONCATENATED MODULE: ./node_modules/c.js 367 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_cjs__ = __webpack_require__(/*! cjs */ 2); 368 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_cjs___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_cjs__); 369 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_shared__ = __webpack_require__(/*! shared */ 0); 370 | // module c 371 | 372 | 373 | var c = String.fromCharCode(__WEBPACK_IMPORTED_MODULE_0_cjs__["c"].charCodeAt(0) - 2); 374 | 375 | 376 | 377 | // CONCATENATED MODULE: ./node_modules/d.js 378 | var d_namespaceObject = {}; 379 | __webpack_require__.d(d_namespaceObject, "a", function() { return a; }); 380 | // module d 381 | var a = "d"; 382 | 383 | // CONCATENATED MODULE: ./lazy.js 384 | /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "c", function() { return c; }); 385 | /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "x", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["a"]; }); 386 | /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "y", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["b"]; }); 387 | /* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "d", function() { return d_namespaceObject; }); 388 | 389 | 390 | 391 | 392 | 393 | /***/ }) 394 | ]); 395 | ``` 396 | 397 | Minimized 398 | 399 | ``` javascript 400 | webpackJsonp([0],[,,function(n,r){r.c="e"},function(n,r,t){"use strict";Object.defineProperty(r,"__esModule",{value:!0});var e=t(2),u=(t.n(e),t(0)),c=String.fromCharCode(e.c.charCodeAt(0)-2),o={};t.d(o,"a",function(){return d});var d="d";t.d(r,"c",function(){return c}),t.d(r,"x",function(){return u.a}),t.d(r,"y",function(){return u.b}),t.d(r,"d",function(){return o})}]); 401 | ``` 402 | 403 | # Info 404 | 405 | ## Uncompressed 406 | 407 | ``` 408 | Hash: 49a2b3b1a85f33063e81 409 | Version: webpack 3.0.0 410 | Asset Size Chunks Chunk Names 411 | 0.output.js 1.93 kB 0 [emitted] 412 | output.js 7.43 kB 1 [emitted] main 413 | Entrypoint main = output.js 414 | chunk {0} 0.output.js 263 bytes {1} [rendered] 415 | > [] 4:0-16 416 | [3] ./lazy.js + 2 modules 221 bytes {0} [built] 417 | [exports: d, c, x, y] 418 | import() ./lazy [] ./example.js 4:0-16 419 | + 1 hidden module 420 | chunk {1} output.js (main) 367 bytes [entry] [rendered] 421 | > main [] 422 | [0] ./node_modules/shared.js + 1 modules 100 bytes {1} [built] 423 | [exports: x, y] 424 | [only some exports used: x, y] 425 | harmony import shared [1] ./example.js + 2 modules 3:0-23 426 | harmony import shared [3] ./lazy.js + 2 modules 6:0-30 427 | [1] ./example.js + 2 modules 267 bytes {1} [built] 428 | [no exports] 429 | ``` 430 | 431 | ## Minimized (uglify-js, no zip) 432 | 433 | ``` 434 | Hash: 49a2b3b1a85f33063e81 435 | Version: webpack 3.0.0 436 | Asset Size Chunks Chunk Names 437 | 0.output.js 373 bytes 0 [emitted] 438 | output.js 1.66 kB 1 [emitted] main 439 | Entrypoint main = output.js 440 | chunk {0} 0.output.js 263 bytes {1} [rendered] 441 | > [] 4:0-16 442 | [3] ./lazy.js + 2 modules 221 bytes {0} [built] 443 | [exports: d, c, x, y] 444 | import() ./lazy [] ./example.js 4:0-16 445 | + 1 hidden module 446 | chunk {1} output.js (main) 367 bytes [entry] [rendered] 447 | > main [] 448 | [0] ./node_modules/shared.js + 1 modules 100 bytes {1} [built] 449 | [exports: x, y] 450 | [only some exports used: x, y] 451 | harmony import shared [1] ./example.js + 2 modules 3:0-23 452 | harmony import shared [3] ./lazy.js + 2 modules 6:0-30 453 | [1] ./example.js + 2 modules 267 bytes {1} [built] 454 | [no exports] 455 | ``` 456 | --------------------------------------------------------------------------------