阮一峰 Webpack 教程

写在开头:

此 Webpack 教程是阮老师在 Webpack 1.x 的版本上做的。现在 Webpack 的版本已经改动较大,建议有基础的同学,就直接上官网看最新的就好了。这个教程可以用来了解下 Webpack 的前世今生。

仓库地址: https://github.com/userkang/webpack-demos-cn

开始

这个项目是一些简单的 Webpack 示例集合

这些示例特意用简单明了的方式编写,你将会发现跟着这些例子学习这个强大的工具并非难事。

如何使用

首先,全局安装 Webpack 和 webpack-dev-server

$ npm i -g webpack webpack-dev-server

然后,克隆这个仓库

$ git clone https://github.com/userkang/webpack-demos-cn.git

安装依赖

$ cd webpack-demos
$ npm install

现在,去项目 demo* 目录下开始源码体验之旅吧

$ cd demo01
$ npm run dev

如果上面的命令没有自动打开浏览器,你可能需要自己在浏览器访问
http://127.0.0.1:8080

前言:什么是 Webpack

Webpack 是为浏览器构建 JavaScirpt 模块脚本的前端工具

它可以像 Browserify 一样使用,并且更加强大

$ browserify main.js > bundle.js
# 相当于
$ webpack main.js bundle.js

Webpack 需要一个 webpack.config.js 的配置文件,它只是一个 CommonJs 模块

// webpack.config.js
module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  }
}

有了这个文件之后,你可以不带参数的调用 Webpack

$ webpack

你需要了解一些命令行选项

  • webpack – 开发环境构建
  • webpack -p – 生产环境构建(压缩混淆脚本)
  • webpack --watch – 监听变动并自动打包
  • webpack -d – 生成 map 映射文件
  • webpack --colors – 构建过程带颜色输出

你可能需要像下面这样在 package.json 中自定义一些脚本 scripts

// package.json
{
  // ...
  "scripts": {
    "dev": "webpack-dev-server --devtool eval --progress --colors",
    "deploy": "NODE_ENV=production webpack -p"
  },
  // ...
}

目录

  1. Entry file
  2. Multiple entry files
  3. Babel-loader
  4. CSS-loader
  5. Image loader
  6. CSS Module
  7. UglifyJs Plugin
  8. HTML Webpack Plugin and Open Browser Webpack Plugin
  9. Environment flags
  10. Code splitting
  11. Code splitting with bundle-loader
  12. Common chunk
  13. Vendor chunk
  14. Exposing Global Variables
  15. React router

Demo01: Entry file (source)

入口文件是 Webpack 进行读取构建 bundle.js 文件的一个文件

例如, main.js 就是一个入口文件.

// main.js
document.write('

Hello World

'
)

index.html

<html>
  <body>
    <script type="text/javascript" src="bundle.js">script>
  body>
html>

Webpack 遵循 webpack.config.js 来构建 bundle.js.

// webpack.config.js
module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  }
}

启动服务,访问 http://127.0.0.1:8080 .

$ cd demo01
$ npm run dev

Demo02: Multiple entry files (source)

多个入口文件也是可以的。在多页面 应用中,每个页面拥有不同的入口文件,用这个就非常管用了。

// main1.js
document.write('

Hello World

'
) // main2.js document.write('

Hello Webpack

'
)

index.html

<html>
  <body>
    <script src="bundle1.js">script>
    <script src="bundle2.js">script>
  body>
html>

webpack.config.js

module.exports = {
  entry: {
    bundle1: './main1.js',
    bundle2: './main2.js'
  },
  output: {
    filename: '[name].js'
  }
}

Demo03: Babel-loader (source)

Loaders 是一种预处理器,它可以在 Webpack 编译之前把你应用中的静态资源进行转换 (更多信息)。

举个例子, Babel-loader 可以在 Webpack 编译这些 JS 文件之前,先将 JSX/ES6 语法的文件转换成普通 ES5 语法的文件。Webpack 官网可以查看目前支持的 loaders。

main.jsx 是一个 JSX 文件.

// main.jsx
const React = require('react')
const ReactDOM = require('react-dom')

ReactDOM.render(<h1>Hello, world!</h1>, document.querySelector('#wrapper'))

index.html

<html>
  <body>
    <div id="wrapper">div>
    <script src="bundle.js">script>
  body>
html>

webpack.config.js

module.exports = {
  entry: './main.jsx',
  output: {
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015', 'react']
          }
        }
      }
    ]
  }
}

上边的代码段用到了 babel-loader, 它需要 Babel 的预设插件 babel-preset-es2015 and babel-preset-react 来转义 ES6 和 React。

Demo04: CSS-loader (source)

Webpack 允许在 JS 文件里包含 CSS,并通过 CSS-loader来预处理 CSS 文件。

main.js

require('./app.css')

app.css

body {
  background-color: blue;
}

index.html

<html>
  <head>
    <script type="text/javascript" src="bundle.js">script>
  head>
  <body>
    <h1>Hello Worldh1>
  body>
html>

webpack.config.js

module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  }
}

注意,你必须用到两个 loaders 去转换 CSS 文件。一个是 CSS-loader 来读取 CSS 文件,另一个是 Style-loader 用来把