webpack

  • 概述

WebPack是一个模块打包工具,管理与打包Web开发中所用到的HTML、 JavaScript 、CSS以及各种静态文件(图片、字体等),让开发过程更加高效。WebPack把项目当作一个整体,通过一个给定的主文件(如 index. js), 从这个文件开始找到项目的所有依赖,并使用 loader(加载器)来处理它们,最后打包成浏览器可识别的文件。

使用各种 loader对各种资源做处理,并解析成浏览器可运行的代码。loader需要在 webpack.config.js里单独用 module进行配置。用来压缩合并CSS和 JavaScript代码;压缩图片,对小图生成base64编码,对大图进行压缩;使用 Babel把 EMAScript 6编译成 EMAScript 5;热重载;局部刷新等。

loader负责处理源文件,如CSS、jsx文件。而 plugins并不直接操作单个文件,它直接对整个构建过程起作用。

WebPack使用许多特性来分割代码,生成多个 bundle js文件,而且异步加载部分代码用于实现按需加载。在 output中配置出口文件,在 entry中配置入口文件。

  • 安装
mkdir webpack-demo && cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev
  • webpack.config.js
const path = require('path');

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

publicPath:正式上线路径设置

output:{
  publicPath:"http://www.myweb.com"
}
  • 刚开始时的目录结构
webpack-demo
|- package.json
|- webpack.config.js
|- /dist
  |- bundle.js
  |- index.html
|- /src
  |- index.js
|- /node_modules

webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。

  • 加载 css
npm install --save-dev style-loader css-loader
  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
+   module: {
+     rules: [
+       {
+         test: /\.css$/,
+         use: [
+           'style-loader',
+           'css-loader'
+         ]
+       }
+     ]
+   }
  };

这使你可以在依赖于此样式的文件中 import './style.css'。现在,当该模块运行时,含有 CSS 字符串的 <style> 标签,将被插入到 html 文件的 <head> 中。

  • 加载图片
npm install --save-dev file-loader
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
        },
+       {
+         test: /\.(png|svg|jpg|gif)$/,
+         use: [
+           'file-loader'
+         ]
+       }
      ]
    }

现在,当你 import MyImage from './my-image.png',该图像将被处理并添加到 output 目录,_并且_ MyImage 变量将包含该图像在处理后的最终 url。当使用 css-loader 时,如上所示,你的 CSS 中的 url('./my-image.png') 会使用类似的过程去处理。loader 会识别这是一个本地文件,并将 './my-image.png' 路径,替换为输出目录中图像的最终路径。html-loader 以相同的方式处理 <img src="./my-image.png" />

  • 加载字体
        {
          test: /\.(png|svg|jpg|gif)$/,
          use: [
            'file-loader'
          ]
        },
+       {
+         test: /\.(woff|woff2|eot|ttf|otf)$/,
+         use: [
+           'file-loader'
+         ]
+       }
  • 加载数据
npm install --save-dev csv-loader xml-loader
+       {
+         test: /\.(csv|tsv)$/,
+         use: [
+           'csv-loader'
+         ]
+       },
+       {
+         test: /\.xml$/,
+         use: [
+           'xml-loader'
+         ]
+       }
  • 当前的目录结构
  webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
    |- data.xml
    |- my-font.woff
    |- my-font.woff2
    |- icon.png
    |- style.css
    |- index.js
  |- /node_modules
  • 多个 js 入口和输出

在 entry 添加 src/print.js 作为新的入口起点(print),然后修改 output,以便根据入口起点名称动态生成 bundle 名称:

module.exports = {
-   entry: './src/index.js',
+   entry: {
+     app: './src/index.js',
+     print: './src/print.js'
+   },
    output: {
-     filename: 'bundle.js',
+     filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };

webpack 自身的多数功能都使用这个插件接口。这个插件接口使 webpack 变得极其灵活

  • 重新生成 index.html
npm install --save-dev html-webpack-plugin
  const path = require('path');
+ const HtmlWebpackPlugin = require('html-webpack-plugin');

  module.exports = {
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
+   plugins: [
+     new HtmlWebpackPlugin({
+       title: 'Output Management'
+     })
+   ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };

将 index.html 打开,你就会看到 HtmlWebpackPlugin 创建了一个全新的文件,所有的 bundle 会自动添加到 html 中。

修改现有html

 + plugins: [
 + new HtmlWebpackPlugin({
 + template: 'src/assets/index.html'
 + })
 + ],

在现有的index.html中引入打包后的js

还能设置 filename(输出的html名称),inject(插入位置如 head),minify,chunks(允许加载的chunks:[]),excludeChunks(排除的chunks)

html页面调用这些配置项的方法:

<%= htmlWebpackPlugin.options.title %>

多页面应用

可以指定多个 new HtmlWebpackPlugin,生成多个html
  • 清理 /dist 文件夹
npm install clean-webpack-plugin --save-dev
  const path = require('path');
  const HtmlWebpackPlugin = require('html-webpack-plugin');
+ const CleanWebpackPlugin = require('clean-webpack-plugin');

  module.exports = {
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
    plugins: [
+     new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Output Management'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };

每次构建之前,清理 dist 文件夹

  • 使用 source map

JavaScript 提供了 source map 功能,将编译后的代码映射回原始源代码。

  module.exports = {
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
+   devtool: 'inline-source-map',
  • 自动编译代码
  1. 启动 webpack 的观察模式的 npm script 脚本,但是不能自动刷新页面
    +     "watch": "webpack --watch",
  2. 使用 webpack-dev-server(推荐)
    npm install --save-dev webpack-dev-server
    devtool: 'inline-source-map',
    +   devServer: {
    +     contentBase: './dist'
    +   },
        plugins: [
    
    以上配置告知 webpack-dev-server,在 localhost:8080 下建立服务,将 dist 目录下的文件,作为可访问文件。 加到 npm script 中 + "start": "webpack-dev-server --open", 
  3. webpack-dev-middleware 是一个容器(wrapper),它可以把 webpack 处理后的文件传递给一个服务器(server)。
npm install --save-dev express webpack-dev-middleware

webpack-dev-middleware 配合 express server

  • webpack4
    需要设置:mode:’development’ 或者 ‘production’
    需要安装:webpack-cli