webpack使用入门

作者: 宁静的夜 | 来源:发表于2017-03-13 15:17 被阅读1502次

    webpack有什么作用?

    Webpack 是一个前端资源加载/打包工具,只需要相对简单的配置就可以提供前端工程化需要的各种功能,并且如果有需要它还可以被整合到其他比如 Grunt / Gulp 的工作流。

    它可以将各种js,css,图片等静态资源打包到一起,统一管理起来。如下图

    Webpack

    webpack版本

    目前webpack主要有v1.x和v2.x两个版本,如果之前使用的webpack版本是1.x,想要升级到2.x,可以参考官方的升级指南。本文主要介绍2.X版本的使用。

    webpack与其它模块打包工具的区别

    如果想看webpack和其它打包工具,如: jrburke/requirejs, substack/node-browserify, jspm/jspm-cli, rollup/rollup, brunch/brunch的对比信息,可以参看官方给的对比表

    安装webpack

    首先,并不建议全局安装webpack,因为这样会限制你在其它项目中使用不同版本的webpack。所以建议webpack随项目安装,在项目根目录下,执行下面的命令( 关于npm的使用,可以参考我之前写的npm使用入门)

    $ npm install webpack --save-dev
    

    验证安装是否成功

    $ node_modules/.bin/webpack -version
    2.2.1
    

    创建第一个打包

    现在我们通过一个简短的例子,来介绍下webpack的使用流程。

    首先,安装好webpack

    $ mkdir webpack-demo && cd webpack-demo
    
    $ npm init -y
    
    $ npm install --save-dev webpack
    

    然后创建一个app目录并在里面创建一个index.js文件。app/index.js文件的内容如下

    app/index.js

    function component () {
      var element = document.createElement('div');
    
      /* lodash is required for the next line to work */
      element.innerHTML = _.join(['Hello','webpack'], ' ');
    
      return element;
    }
    
    document.body.appendChild(component());
    

    index.js的功能很加单,就是在页面body标签下添加一个Hello webpack的字符串。
    为了使用上面的index.js文件,还需要在与app同级目录下创建一个index.html文件。

    index.html

    <html>
      <head>
        <title>webpack 2 demo</title>
        <script src="https://unpkg.com/lodash@4.16.6"></script>
      </head>
      <body>
        <script src="app/index.js"></script>
      </body>
    </html>
    

    安装lodash依赖

    $ npm install --save lodash
    

    用浏览器打开index.html文件,可以看到如下浏览器输出"Hello Webpack"。

    我们来看看现在上面的做法有哪些问题:

    首先在上面的index.html文件里,通过script标签指定了依赖lodash关系。但是在index.html文件里面看不到它哪里依赖了lodash

    index.js在它运行之前依赖lodash,但是在index.js文件里面并没有明确的指出它依赖lodash,只是在脚本里看到使用了个全局变量_

    通过这种方式来管理javascript容易出现下面的问题:

    1. 如果依赖缺失或者引入的顺序不对, 会导致整个应用无法正常工作。
    2. 如果一个依赖引入了但是又没有使用到,浏览器在运行项目时又会白白去下载他们,然而却不会被使用到。

    问题既然出现了,那么我们看看使用webpack如何来解决上面的问题。

    首先,安装lodash依赖(前面如果已经做过,这步可以跳过)

    $ npm install --save lodash
    

    然后引入lodash,修改app/index.js。在最顶部添加上import _ from lodash;。现在的app/index.js内容如下:

    app/index.js

    import _ from 'lodash';
    function component() {
        var element = document.createElement('div');
        element.innerHTML = _.join(["Hello", "World"], ' ');
        return element;
    }
    document.body.appendChild(component());
    

    同时修改index.html,去掉依赖声明<script src="https://unpkg.com/lodash@4.16.6"></script>, 并且将引用app/index.js修改了dist/bundle.js

    index.html

    <html>
      <head>
        <title>webpack 2 demo</title>
      </head>
      <body>
          <script src="dist/bundle.js"></script>
      </body>
    </html>
    

    现在app/index.js明确得指明了依赖lodash, 并且变量_也不会造成全局变量污染。

    用这种方式声明依赖,webpack在最终打包的时候,首先会利用这些声明构建依赖关系图,确保引入依赖顺序的正确性,同时也会删除掉那些声明了但却没有使用到的依赖信息。

    现在我们可以使用webpack命令在进行打包

    $ ./node_modules/.bin/webpack app/index.js dist/bundle.js
    
    Hash: fabaab5724cd666116a7
    Version: webpack 2.2.1
    Time: 490ms
        Asset    Size  Chunks                    Chunk Names
    bundle.js  544 kB       0  [emitted]  [big]  main
       [0] ./~/lodash/lodash.js 540 kB {0} [built]
       [1] (webpack)/buildin/global.js 509 bytes {0} [built]
       [2] (webpack)/buildin/module.js 517 bytes {0} [built]
       [3] ./app/index.js 216 bytes {0} [built]
    

    dist/bundle.js文件里,生成了最终的打包信息。
    用浏览器打开index.html, 可以看到输出效果。

    使用ES6(ES2015)和webpack

    你可能已经注意到,在app/index.js文件里面,我们引用了ES6的语法import _ from 'lodash'。尽管这个语法现在还并不被直接被浏览器所支持, 但是我们的代码仍然能被浏览器执行,这是因为webpack对import/export这些语句做了兼容处理,可以在生成的dist/bundle.js里看到对于兼容的处理。

    但是,需要注意的是。除了improt/export之外,其它使用到的ES6的语法,webpack是不支持的,需要使用BabelBublé做语法转换。

    使用配置文件

    如果有更复杂的配置信息,我们可以使用配置文件来使用webpack打包代码。只需要创建一个webpack.config.js配置文件来执行上面的命令。

    webpack.config.js

    var path = require('path');
    
    module.exports = {
      entry: './app/index.js',
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
      }
    };
    

    首先删除前面生成的dist/bundle.js文件,避免影响判断后面使用配置文件是否成功。再执行下面的命令

    $ ./node_modules/.bin/webpack --config webpack.config.js
    
    Hash: fabaab5724cd666116a7
    Version: webpack 2.2.1
    Time: 425ms
        Asset    Size  Chunks                    Chunk Names
    bundle.js  544 kB       0  [emitted]  [big]  main
       [0] ./~/lodash/lodash.js 540 kB {0} [built]
       [1] (webpack)/buildin/global.js 509 bytes {0} [built]
       [2] (webpack)/buildin/module.js 517 bytes {0} [built]
       [3] ./app/index.js 216 bytes {0} [built]
    

    小贴士
    如果使用默认的webpack.config.js文件名,webpack会自动去使用它,可以省去参数--config webpack.config.js

    配置文件使用非常灵活,可以把加载规则,配置插件等其它增加我们打包功能的指令全部放在里面。

    使用webpack和npm

    我们也可以把webpack和npm结合起来,将命令添加到package.json文件里面,以后所有的命令就由npm来统一管理。操作非常简单,只需要修改package.json文件,添加如下内容即可。

    {
      ...
      "scripts": {
        "build": "webpack"
      },
      ...
    }
    

    因为npm命令启动的时候会自动从项目目录下加载环境变量,所以,不需要指定webpack命令的绝对路径,npm会自动找到它并把它调用起来。
    直接运行命令npm run build即可。

    $ npm run build
    
    > webpack-demo@1.0.0 build /private/tmp/webpack-demo
    > webpack
    
    Hash: fabaab5724cd666116a7
    Version: webpack 2.2.1
    Time: 447ms
        Asset    Size  Chunks                    Chunk Names
    bundle.js  544 kB       0  [emitted]  [big]  main
       [0] ./~/lodash/lodash.js 540 kB {0} [built]
       [1] (webpack)/buildin/global.js 509 bytes {0} [built]
       [2] (webpack)/buildin/module.js 517 bytes {0} [built]
       [3] ./app/index.js 216 bytes {0} [built]
    

    本来完整的命令是./node_modules/.bin/webpack --config webpack.config.js,由于前面提到过使用默认配置文件名时,配置文件名参数可以省略,即相当于执行./node_modules/.bin/webpack,然后因为和npm结合,./node_modules/.bin/webpack的绝对路径信息也可以省略掉,成了webpack命令,跟我们在package.json里添加的一样。

    {
      ...
      "scripts": {
        "build": "webpack"
      },
      ...
    }
    

    结尾

    通过上面的例子,我们已经掌握了一些基本的打包技巧,为了更加全面的使用webpack,可以继续深入了解

    另外附上一个自己看到的觉得不错的教程:
    webpack入坑之旅

    相关文章

      网友评论

        本文标题:webpack使用入门

        本文链接:https://www.haomeiwen.com/subject/jsafnttx.html