webpack实质上是一个自动化的模块打包机。从入口文件js开始分析项目的依赖,将js 、CSS或者图片等类型的文件使用loader或插件进行处理,打包成一个或多个合适的文件。

与Gulp/Grunt对比

Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,工具之后可以自动替你完成这些任务

webpack的工作方式是:把你的项目依赖最后打包为一个(或多个)浏览器可识别的JavaScript文件

最简单的webpack使用

  1. 初始化webpack项目
mkdir demo && cd demo
## package.json初始化
npm init
## 安装webpack到本地开发环境
npm install -save--dev webpack
  1. 命令行运行
./node_modules/.bin/webpack src/index.js dist/bundle.js
              ↓                  ↓             ↓
           打包指令            入口文件      输出文件
全局安装webpack时:
webpack src/index.js dist/bundle.js

命令后面还可以加以下参数:

  • --watch 实时打包
  • --process 显示打包进度
  • --display-modules 显示打包的模块
  • --display-reasons 显示模块包含在输出中的原因
  1. webpack.config配置文件

也可以使用webpack.config配置文件代替指定入口文件和输出文件

const path = require('path')

module.exports = {
  entry: './src/index.js',  // 入口文件
  output: {
    filename: 'bundle.js',  // 输出文件名
    path: path.resolve(__dirname, 'dist') // 输出地址
  }
}

可以通过配置package.json文件中的scripts属性,来自定义脚本

scripts: {
  "build": "webpack --config webpack.config.js"
}
  1. 引用打包后的文件
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>webpackTest</title>
</head>
<body>
  <script src="./bundle.js"></script>
</body>
</html>

webpack核心概念

  • entry 入口: 指示webpack应该使用哪个模块,来作为构建其内部依赖图的开始
  • output 输出: 告诉webpack在哪里输出它所创建的bundles,以及如何命名这些文件
  • loaders: 将其他类型文件转换成webpack识别的类型 使用时,先install相应的loader,然后再module->rules数组中进行配置

打包css

module: {
  rules: [{
    test: /\.css$/,                                         // 识别需要处理的类型
    use: [{loader: 'style-loader'}, {loader: 'css-loader'}] // 使用loader去转换
  }]
}

打包图片

npm install --save-dev file-loader
  • plugins 插件: 提供其他方面的支持 使用插件时,需先要require()它,然后把它添加到Plugins数组中。也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用new创建实例 ``` js const HtmlWebpackPlugin = require(‘html-webpack-plugin’) const path = require(‘path’)

const config = { entry: ‘./main.js’, output: { path: path.resolve(__dirname,‘dist’), filename: ‘bundle.js’ }, module: { rules:[ { test: /.css$/, use: [ { loader: ‘style-loader’ }, { loader: ‘css-loader’ } ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: ‘./index.html’ }) ] }

module.exports = config


## 多入口设置

我们一般是打包成一个`bundle.js`文件,但如果代码越来越复杂,就需要打包成多个文件,在`index.html`里面去引用。不多说,直接上代码:

``` js
const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')

const config = {
  entry: {
    component1: './main1.js',
    component2: './main2.js',
  },
  output: {
    path: path.resolve(__dirname,'dist'),
    filename: '[name].bundle.js'
  },
  module: {
    rules: [
      { test: /\.css$/, loader: 'style-loader!css-loader' }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({ template: './index.html' })
  ]
}

module.exports = config

输出文件名中的[name]表示entry里面指定的名称,最终生成:component1.bundle.jscomponent2.bundle.js

html-webpack-pugin 插件

html-webpack-pugin主要解决html文件中需要手动插入或修改打包后的文件问题。

上面运行完webpack命令后,生成的index.html文件新引入component2后引入component1

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>first_webpack_demo</title>
</head>
<body>
  <script type="text/javascript" src="component2.bundle.js"></script>
  <script type="text/javascript" src="component1.bundle.js"></script>
</body>
</html>

html-webpack-plugin 中的参数

webpack-dev-server

webpack-dev-server可以帮你在代码发生改变的时候自动打包

devServer: {
  contentBase: path.resolve(__dirname, 'dist'),
  host: 'localhost',
  port: 8080,
}
"scripts": {
  "dev": "webpack-dev-server --config webpack.dev.js"
}

热加载HMR

HRM能够让应用运行的时候替换、增加或删除模块,而无需进行完全的重载

devServer: {
  contentBase: path.resolve(__dirname, 'dist'),
  hot: true, // 告诉 dev-server 使用 HMR
  hotOnly: true // 如果热加载失败了禁止刷新页面,可以分析失败原因
  host: 'localhost',
  port: 8080,
},
plugins: [
  new webpack.HotModuleReplacementPlugin()
]

[HMR] Waiting for update signal from WDS...说明启用HMR成功

热加载HMRwebpack-dev-server的区别是,webpack-dev-server编译更新之后,直接重新刷新页面,而HMR则是尝试先替换掉相关的模块,不使页面刷新。

参考

多入口设置与 html-webpack-pugin 插件详解 初级webpack配置工程师的弃坑之路