为了账号安全,请及时绑定邮箱和手机立即绑定

What's webpack 总结分析

标签:
前端工具
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" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://xxx/js/main-24ba9f649a141397d321.js"></script><script type="text/javascript" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="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
点击查看更多内容
10人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
7245
获赞与收藏
3476

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消