webpack配置介绍

mode

模式:"production" | "development" | "none"
不同的模式会对 webpack 打包时进行一些对应的优化配置。
development模式下的打包,不会压缩打包后文件的体积
production模式下的打包,会压缩打包后的文件体积
所以开发过程中用development,推送上线的时候用production

entry

指定打包⼊口⽂文件,有三种不同的形式:string | object | array
一对一:一个入口、一个打包文件:

module.exports = {
  entry: './src/index.js'
}

多对一:多个入口、一个打包文件

module.exports = {
  entry: [
    './src/index1.js',
    './src/index2.js',
  ]
}

多对多:多个入口、多打包文件

module.exports = {
  entry: {
    'index1': "./src/index1.js",
    'index2': "./src/index2.js"
  }
}

output

打包后的文件位置

module.exports = {
  ...,
  output: {
    path: path.resolve(__dirname, "dist"), // //输出文件的存放路径
        filename: "bundle.js", // 指定一个固定的文件名称
        filename: "[name].js" // 文件名字为entry对象的key值
    }
}

可以指定一个固定的文件名称,如果是多入口多出口(entry 为对象),则不能使用单文件出口,需要使用下面的方式。
通过 webpack 内置的变量占位符:[name]

webpack 默认情况下只能处理 js 模块,如果需要处理其它类型的模块,则需要使用它提供的一些其它功能,如loaders、plugins,可以处理非js文本、css、图片等

Loaders

module.exports = {
  ...,
  module: {
    rules:[
        {
            test:/\.xxx$/,
        use:{
            loader: 'xxx-load'
        }
            }
    ]
    }
}

webpack 碰到不识别的模块的时候,webpack 会在配置的 module 中进行该文件解析规则的查找
rules 就是我们为不同类型的文件定义的解析规则对应的 loader,它是一个数组。
每一种类型规则通过 test 选项来定义,通过正则进行匹配,通常我们会通过正则的方式来匹配文件后缀类型。
use 针对匹配到文件类型,调用对应的 loader 进行处理

常用的loader:
raw-loader
file-loader
url-loader
css-loader 分析 css 模块之间的关系,并合成⼀个 css
style-loader 把 css-loader 生成的内容,用 style 标签挂载到⻚面的 head

rules: [
  ...,
    {
        test: /\.css$/,
    use: ["style-loader", "css-loader"]
    }
]

同一个任务的 loader 可以同时挂载多个,处理顺序为:从右到左,也就是先通过 css-loader 处理,然后把处理后的 css 字符串交给 style-loader 进行处理

Plugins

扩展 webpack 本身的一些功能,它们会运行在 webpack 的不同阶段(钩子 / 生命周期)

HtmlWebpackPlugin
在打包结束后,⾃动生成⼀个 html ⽂文件,并把打包生成的 js 模块引⼊到该 html
安装:

npm install --save-dev html-webpack-plugin

使用:
在webpack.config.js文件中配置plugins

const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
    ...
  plugins: [
     new HtmlWebpackPlugin({
       title: "My App", // 页面的title
       filename: "app.html", // 生成的html文件名字
       template: "./src/html/index.html" // 引用的html模板
     }) 
  ]
};

clean-webpack-plugin
安装:

npm install -D clean-webpack-plugin

删除(清理)构建目录

const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
    ...
  plugins: [
    ...,
    new CleanWebpackPlugin(),
    ...
  ]
}

mini-css-extract-plugin
提取 CSS 到一个单独的文件中

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    ...,
  module: {
    rules: [
        {
            test: /\.s[ac]ss$/,
            use: [
                {
                    loader: MiniCssExtractPlugin.loader
                    },
          'css-loader',
          'sass-loader'
        ]
            }
    ]
    },
  plugins: [
    ...,
    new MiniCssExtractPlugin({
        filename: '[name].css'
    }),
    ...
  ]
}

sourceMap

我们实际运行在浏览器的代码是通过 webpack 打包合并甚至是压缩混淆过的代码,所生成的代码并不利于我们的调试和错误定位,我们可以通过 sourceMap 来解决这个问题,sourceMap 本质是一个记录了编译后代码与源代码的映射关系的文件,我们可以通过 webpackdevtool 选项来开启 sourceMap

module.exports = {
  mode: 'production',
  devtool: 'source-map',
  ...
}

WebpackDevServer

每次的代码修改都需要重新编译打包,刷新浏览器,特别麻烦,我们可以通过安装 webpackDevServer 来改善这方面的体验

npm install --save-dev webpack-dev-server

启动命令:

"scripts": {
  "server": "webpack-dev-server"
}

修改 webpack.config.js

module.exports = {
  ...,
  devServer: {
    // 自动开启浏览器
    open: true,
    // 端口
    port: 8081
    }
}

启动服务以后,webpack 不在会把打包后的文件生成到硬盘真实目录中了,而是直接存在了内存中(同时虚拟了一个存放目录路径),后期更新编译打包和访问速度大大提升

Proxy

服务端代理,处理跨域问题

module.exports = {
  ...,
  devServer: {
    // 自动开启浏览器
    open: true,
    // 端口
    port: 8081,
    proxy: {
//拦截/api开头的请求,并把/api替换成/data
      '/api': {
        target: 'http://localhost:8787',
 pathRewrite: {
          "^/api": "/data",
        },
        }
    }
    }
}

通过 proxy 设置,当我们在当前 WebpackDevServer 环境下发送以 /api 开头的请求都会被转发到 http://localhost:8787 目标服务器下

Hot Module Replacement

在之前当代码有变化,我们使用的 live reload,也就是刷新整个页面,虽然这样为我们省掉了很多手动刷新页面的麻烦,但是这样即使只是修改了很小的内容,也会刷新整个页面,无法保持页面操作状态。HMR 随之就出现了,它的核心的局部(模块)更新,也就是不刷新页面,只更新变化的部分

module.exports = {
  ...,
  devServer: {
    // 自动开启浏览器
    open: true,
    // 端口
    port: 8081,
    // 开启热更新
    hot:true,
    // 即使 HMR 不生效,也不去刷新整个页面(选择开启)
    hotOnly:true,
    proxy: {
      '/api': {
        target: 'http://localhost:8787'
        }
    }
    }
}

index.js文件

import fn1 from './fn1.js';
box1.onclick = fn1;

if (module.hot) {//如果开启 HMR
    module.hot.accept('./fn1.js', function() {
      // 更新逻辑
      box1.onclick = fn1;
    })
}

上面代码就是 当 ./fn1.js 模块代码发生变化的时候,把最新的 fn1 函数绑定到 box1.onclick 上
从上面就可以看到,HMR 其实就是以模块为单位,当模块代码发生修改的时候,通知客户端进行对应的更新,而客户端则根据具体的模块来更新我们的页面逻辑(这些逻辑需要自己去实现),好在当前一些常用的更新逻辑都有了现成的插件

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容