继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

What's webpack 总结分析

resharpe
关注TA
已关注
手记 102
粉丝 7244
获赞 3476
What's webpack

webpack takes modules with dependencies and generates static assets representing those modules.webpack处理模块依赖并生成代表这些依赖的静态资源。

![what-is-webpack.png][https://webpack.github.io/assets/what-is-webpack.png]

  • goals:
    • Split the dependency tree into chunks loaded on demand将依赖关系树拆分为按需加载的块
    • Keep initial loading time low保持较低的初始加载时间
    • Every static asset should be able to be a module一切皆模块
    • Ability to integrate 3rd-party libraries as modules能够将第三方库集成为模块
    • Ability to customize nearly every part of the module bundler能够定制模块bundler的几乎每个部分
    • Suited for big projects适应大项目开发
  • How is webpack different?不同寻常之处
    • Code Splitting代码分割
    • Loaders加载器
    • Clever parsing智能解析
    • Plugin system插件系统 使用
  • via npm
    npm install webpack -g//实际开发中建议作为开发依赖安装
  • get started

    1. mkdir webpack-test cd webpack-test npm init //npm初始化,生成package.json文件
    2. 生成如下文件
      
      name: (webpack-test)
      version: (1.0.0)
      description:
      entry point: (index.js)
      test command:
      git repository:
      keywords:
      author:
      license: (ISC)
      About to write to C:\Users\立\Desktop\webpack-test\package.json:

    {
    "name": "webpack-test",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "license": "ISC"
    }
    Is this ok? (yes) yes

    
    - 退出,然后安装webpack,开发依赖
    ```npm install webpack --save-dev```
    - 新建hello.js文件
     ```touch hello.js```
    - 运用webpack打包hello.js到hello.bundle.js
    ```webpack hello.js hello.bundle.js
    Hash: e1f84d93f0d8fe61c001
    Version: webpack 2.2.1
    Time: 75ms
              Asset     Size  Chunks             Chunk Names
    hello.bundle.js  2.55 kB       0  [emitted]  main
       [0] ./hello.js 44 bytes {0} [built]

    Asset:本次打包生成的文件,Size指文件大小,Chunks本次打包的分块,Chunk Names
    块名。可以在hello.bundle.js文件尾部看到打包好的文件

    • 新建一个world.js文件,并在hello.js中通过require语法引入,查看webpack工作机制
      touch world.js
      //随便写些内容world.js
      function world() {
      return {}
      }
      //hello.js
      require('./world')
      function hello() {
      console.log('hello')
      }
      webpack hello.js hello.bundle.js//打包
      // hello.bundle.js
      ...
      /******/ ([
      /* 0 */
      /***/ (function(module, exports) {  
      function world() {
      return {}
      }    
      /***/ }),
      /* 1 */
      /***/ (function(module, exports, __webpack_require__) {    
      __webpack_require__(0)   //require被替换成webpack内置的require,以此处理
      function hello() {
      console.log('hello')
      }
      /***/ })
      ...
    • webpack处理css文件
      ```touch style.css
      //style.css
      html,body{
      padding:0;
      }
      //hello.js
      ...
      require('./style.css')
      ...
      webpack hello.js hello.bundle.js//打包,报错
      Hash: 643f99ddedb412fd4aa2
      Version: webpack 2.2.1
      Time: 80ms
      Asset Size Chunks Chunk Names
      hello.bundle.js 2.98 kB 0 [emitted] main
      [0] ./style.css 211 bytes {0} [built] [failed] [1 error]
      [1] ./world.js 33 bytes {0} [built]
      [2] ./hello.js 90 bytes {0} [built]

    ERROR in ./style.css
    Module parse failed: C:\Users\立\Desktop\webpack-test\style.css Unexpected token (1:9)
    You may need an appropriate loader to handle this file type.
    | html,body{
    | padding:0;
    | }
    @ ./hello.js 2:0-22
    //需要合适loader去处理此类文件
    cnpm install css-loader style-loader --save-dev
    //再次打包还是报错,因为css-loader未引入
    //hello.js
    require('css-loader!./style.css')//修改,引入,再打包,成功
    Hash: 6006c7ab0c2329fd08c1
    Version: webpack 2.2.1
    Time: 4593ms
    Asset Size Chunks Chunk Names
    hello.bundle.js 4.46 kB 0 [emitted] main
    [0] ./~/.0.26.2@css-loader!./style.css 192 bytes {0} [built]
    [1] ./world.js 33 bytes {0} [built]
    [2] ./~/.0.26.2@css-loader/lib/css-base.js 1.46 kB {0} [built]
    [3] ./hello.js 101 bytes {0} [built]
    //hello.bundle.js
    exports.push([module.i, "html,body{\r\n\tpadding:0;\r\n}", ""]);

    - 查看效果
    ```touch index.html
    //html
    <script src='hello.bundle.js'></script>
    //hello.js
    hello();
    //style.css
    body{
        background: red;
    }
    //打包,chrome打开index.html发现方法执行了,但css样式没有体现;此时要使用style-loader
    //hello.js
    require('style-loader!css-loader!./style.css')
    //css-loader:使webpack可以处理css文件,style-loader:把生成的css文件生成style标签插入到html文件
    //打包,css生效
    • 直接在命令行也可以指定相应loader,文件改变自动刷新
      //将hello.js修改相应语句如下
      require('./style.css')//然后执行,如果模块绑定在require语句已写则会报错
      webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader'```
      ```webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader' --watch```
      ```webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader' --progress --display-modules 
      --display-reasons```

      Version: webpack 2.2.1
      Time: 783ms
      Asset Size Chunks Chunk Names
      hello.bundle.js 12.4 kB 0 [emitted] main
      [0] ./style.css 927 bytes {0} [built]
      cjs require ./style.css [5] ./hello.js 3:0-22
      [1] ./world.js 33 bytes {0} [built]
      cjs require ./world [5] ./hello.js 1:0-18
      [2] ./~/.0.13.2@style-loader/addStyles.js 6.91 kB {0} [built]
      cjs require !./node_modules/.0.13.2@style-loader/addStyles.js [0] ./style.css 7:13-73
      [3] ./~/.0.26.2@css-loader!./style.css 232 bytes {0} [built]
      cjs require !!./node_modules/.0.26.2@css-loader/index.js!./style.css [0] ./style.css 4:14-81
      [4] ./~/.0.26.2@css-loader/lib/css-base.js 1.46 kB {0} [built]
      cjs require ./node_modules/.0.26.2@css-loader/lib/css-base.js [3] ./~/.0.26.2@css-loader!./style.css 1:27-87
      [5] ./hello.js 154 bytes {0} [built]

      
      ## 基本配置
      配置目录结构
  • webpack.config.js文件
    直接使用webpack命令的时候,webpack会直接到根目录默认运行此文件,注意filename必须这么写否则报错;
    使用
    ```webpack --config可以指定执行的文件
    $ npm run webpack

webpack-demo@1.0.0 webpack D:\me\webpack\webpack-demo
webpack --config webpack.config.js --progress --display-modules --colors --display-reasons
Hash: 4db1453ee63295cf9789 Version: webpack 2.2.1
Time: 92ms
Asset Size Chunks Chunk Names
bundle.js 2.9 kB 0 [emitted] main
[0] ./src/script/a.js 42 bytes {0} [built]
single entry ./src/script/a.js [2] multi ./src/script/main.js ./src/script/a.js main:100001
[1] ./src/script/main.js 34 bytes {0} [built]
single entry ./src/script/main.js [2] multi ./src/script/main.js ./src/script/a.js main:100000
[2] multi ./src/script/main.js ./src/script/a.js 40 bytes {0} [built]

  • entry:入口/output:出口,类是字符串(单路径)或数组(多路径)或对象(多页面)
    如果是多页面,当输出到一个文件时会报错;解决方案是指定输出文件的name及hash或chunkhash 自动化生成html文件
  • html-webpack-plugin 插件的引入
    
    //webpack.config.js
    var htmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: {
main: './src/script/main.js',
a: './src/script/a.js',
},
output: {
path: './dist/js',
filename: '[name]-[chunkhash].js',
},
plugins: [
new htmlWebpackPlugin({
filename: 'index.html',
template: 'index.html', //默认输出路径与output文件同级
inject: 'head',
title: 'hello webpack',
body: new Date(),
})
]
}
//根目录上的index.html 可以用模板语法
<body>
<%= htmlWebpackPlugin.options.date%>
<% for (var key in htmlWebpackPlugin.files){%>
<%= key%>:<%= JSON.stringify(htmlWebpackPlugin.files[key])%>
<%}%>
<% for (var key in htmlWebpackPlugin.options){%>
<%= key%>:<%= JSON.stringify(htmlWebpackPlugin.options[key])%>
<%}%>
</body>
//输出为
<script type="text/javascript" src="https://xxx/js/main-24ba9f649a141397d321.js"></script><script type="text/javascript" src="https://xxx/js/a-578494e863a09d793170.js"></script></head>
<body>
Wed Mar 08 2017 15:52:18 GMT+0800 (中国标准时间)

    publicPath:"https://xxx/"

    chunks:{"main":{"size":34,"entry":"https://xxx/js/main-24ba9f649a141397d321.js","hash":"24ba9f649a141397d321","css":[]},"a":{"size":31,"entry":"https://xxx/js/a-578494e863a09d793170.js","hash":"578494e863a09d793170","css":[]}}

    js:["https://xxx/js/main-24ba9f649a141397d321.js","https://xxx/js/a-578494e863a09d793170.js"]

    css:[]

    manifest:

    template:"D:\\me\\webpack\\webpack-demo\\node_modules\\html-webpack-plugin\\lib\\loader.js!D:\\me\\webpack\\webpack-demo\\index.html"

    filename:"index.html"

    hash:false

    inject:"head"

    compile:true

    favicon:false

    minify:{"removeComments":true}

    cache:true

    showErrors:true

    chunks:"all"

    excludeChunks:[]

    title:"hello webpack"

    xhtml:false

    date:"2017-03-08T07:52:18.883Z"

</body>

- minify:可以设置输出文件格式
- 多页面配置

module.exports = {
entry: {
main: './src/script/main.js',
a: './src/script/a.js',
b: './src/script/b.js',
c: './src/script/c.js',
},
output: {
path: './dist', //输出
filename: 'js/[name]-[chunkhash].js',
publicPath: 'https://xxx', //占位符,上线以后的地址
},
plugins: [
new htmlWebpackPlugin({
filename: 'a.html',
template: 'index.html',
inject: 'body',
chunks: ['main', 'a'],
title: 'hello a.html',
}),
new htmlWebpackPlugin({
filename: 'b.html',
template: 'index.html',
inject: 'body',
chunks: ['b'],
title: 'hello b.html',
}),
new htmlWebpackPlugin({
filename: 'c.html',
template: 'index.html',
inject: 'body',
chunks: ['c'],//对应模板文件
title: 'hello c.html',
})
]
}

- 多页面内联脚本配置

plugins: [
new htmlWebpackPlugin({
filename: 'a.html',
template: 'index.html', //默认输出路径与output文件同级
inject: false,
excludeChunks: ['b', 'c'],
title: 'hello a.html',
}),
new htmlWebpackPlugin({
filename: 'b.html',
template: 'index.html', //默认输出路径与output文件同级
inject: false,
excludeChunks: ['c', 'a'],
title: 'hello b.html',
}),
new htmlWebpackPlugin({
filename: 'c.html',
template: 'index.html', //默认输出路径与output文件同级
inject: false,
excludeChunks: ['b', 'a'],
title: 'hello c.html',
})
]
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title%></title>
<script>
<%=
compilation.assets[htmlWebpackPlugin.files.chunks.main.entry.substr(htmlWebpackPlugin.files.publicPath.length)].source()
%>
</script>
</head>
<body>
<% for(var k in htmlWebpackPlugin.files.chunks){ %>
<% if (k !=='main'){ %>
<script type='text/javascript' src='<%= htmlWebpackPlugin.files.chunks[k].entry%>'></script>
<% }%>
<% }%>
<!-- ok -->
</body>
</html>

## 处理项目中的资源文件
- loader

//...
var path = require('path');
//...
module: {
loaders: [{
test: /.js$/,
loader: 'babel-loader',
exclude: path.resolve(__dirname, 'node_modules'), //运行在根目录,绝对路径
// include: path.resolve(__dirname, 'src/'),
include: './src/',
query: {
presets: ['es-2015']
}
}]
},
//...


- css-loader/style-loader
打开App,阅读手记
10人推荐
发表评论
随时随地看视频慕课网APP