Webpack学习笔记

Webpack 学习笔记。

是什么?

官方给到的解释:

webpack is a static module bundler for modern JavaScript applications.

它是一款针对JS应用的静态模块打包工具,当使用webpack处理应用程序时,它会在内部建一个依赖关系图,这个图能映射应用需要的每一个module并生成一个或多个bundles。

2018.3.12,Webpack4.0 正式发布,Sean T. Larkin 在当天发表了文章webpack 4: released today!!, 列出了新版的变动。通过查看releases可以得到changelog, 目前的最新版本是4.8.3

使用webpack来打包module时,需要设定配置文件,默认的配置文件是webpack.config.js,不过对于4.0及以上的版本,webpack已经不再强制要求配置文件了。针对需要设定的属性,有其相对应的默认值。

在使用webpack前,有必要了解一些重要的概念。

几个重要的概念

  • Entry

    entry用于告诉webpack从哪个文件开始创建内部的依赖关系图,默认情况下是./src/index.js。 我们也可以在配置文件webpack.config.js中自定义,比如:

    module.exports = {
      entry: './path/file.js'  
    };
    

    entry可以有多个,比如:

    const config = {
        entry: {
            pageOne: './src/pageOne/index.js',
            pageTwo: './src/pageTwo/index.js',
            pageThree: './src/pageThree/index.js'
        }
    };
    module.exports = config;
    

    这里设置了三个entries,告诉webpack要生成三个独立的内部依赖图。

  • Output

    output用于告诉webpack,打包编译后的文件放在哪里。主要通过给filename和path赋值的方式来指定。

    看个例子:

    const config = {
        output: {
            filename: 'bundle.js',
            path: '/home/project/public/assets'
        }
    };
    module.exports = config;
    

    这里告诉webpack,最后的输出文件是bundle.js, 存放在'/home/project/public/assets'下。

    上面提到了entry可以有多个,但是output只能有一个,不能配置多个。那么如何让每一个entry都有一个output文件而不是混合在一起呢?官方给到了一个这样的例子做参考:

    {
        entry: {
            app: './src/app.js',
            search: './src/search.js',
        },
        output: {
            filename: '[name].js',
            path: __dirname + '/dist
        }
    }
    

    这样会在/dist下面输出两个打包后的文件,./dist/app.js, ./dist/search.js.

  • Loaders

    loaders用于告诉webpack,不同的文件需要用什么加载器进行处理,比如把其他非JS文件,如TS,转换成JS,或者import一些CSS文件。loader好比在导入或者加载文件时,对文件进行了一次预处理,使之符合打包要求。

    设定loaders有三种方式:

    • 在配置文件中设定

      比如需要加载css,转换ts文件,可以这么用:

      先在本地安装对应的loaders:

      npm install --save-dev css-loader
      npm install --save-dev ts-loader
      

      然后在配置文件中指定用哪个loader处理哪些文件:

      module.exports = {
        module: {
            rules: [
              { test: /\.css$/, use: 'css-loader' },
              { test: /\.ts$/, use: 'ts-loader' }
            ]
        }  
      };
      

      这里告诉webpack,用css-loader处理.css文件,用ts-loader处理.ts文件。

    • import中声明

      比如:

      import Styles from 'style-loader!css-loader?modules!./styles.css';
      

      这里用style-loader和css-loader来处理modules和./styles.css

    • 使用命令行

      看官方给出的例子:

      webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
      

      这里告诉webpack,用jade-loader处理.jade 文件, 用style-loader和css-loader处理.css文件。

      官方还给到了loader 列表以及如何write your own loader

  • Plugins

    loader可以用来转换某些类型的module,而plugin则用来扩展webpack的功能,比如优化bundle,管理assets。

    Tapable可以提供简单的plugin接口,官方还给出了如何自己写一个plugin的教程write a plugin.

    在使用某个plugin之前,需要用require()来将它先添加到plugins 数组中。调用时,则需要使用new来创建一个plugin的实例。

    看个官方给到的例子:

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const webpack = require('webpack');
    const config = {
        module: {
            rules: [
                {test: /\.txt$\/, use: 'raw-loader'}
            ]
        },
        plugins: [
          new  HtmlWebpackPlugin({template: './src/index.html'});     
        ]
    };
    module.exports = config;
    

    这里使用html-webpack-plugin这个plugin,将会自动生成一个index.html文件。

    戳这里查看目前的plugin list。

  • Mode

    mode用于告诉webpack, 根据mode指定的环境来启用webpack的内置优化,其实是启用了对应每个环境下的默认plugins,mode默认值是production,即生产环境。

    mode的取值可以为production,development,或者none。取值为none就是不用任何默认的plugin来优化。

    可以通过命令行或者config文件来设置mode:

    • 配置文件

      module.exports = {
          mode: 'development'
      };
      
    • 命令行

      webpack --mode=development
      

安装

分本地安装和全局安装:

  • global installation

    npm install --global webpack
    

    全局安装会让你固定在特定版本的webpack,对于使用不同版本webpack的项目而言,不是件好事。

  • local installation

    npm install --save-dev webpack
    

    这会在本地安装最新版的webpack,如果需要安装指定版本,可以执行:

    npm install --save-dev webpack@<version> ## version是版本号
    

常用命令

启动:

webpack

让webpack 时时编译:

webpack --build

自定义配置文件:

webpack --config yourconfig.js

补充

如果你也是和我一样的JS新手,在了解Webpack前,有必要对模块及模块化打包进行更为清晰的了解。推荐阅读Preethi Kasireddy的这两篇JavaScript Modules: A Beginner’s GuideJavaScript Modules Part 2: Module Bundling, 对于理解JS中的module 以及为何要bundle module有很大帮助,文中还对比了下webpack与Browserify, RequireJS等其他module bundle的差异,很有启发性。

参考

webpack 官网

webpack 4: released today!!

JavaScript Modules: A Beginner’s Guide

JavaScript Modules Part 2: Module Bundling

Webpack学习之路