webpack 配置介绍

一、webpack        

 

        webpack 仅是一个打包工具,不会处理打包过程的东西例如 es6等新特性,如果需要处理这些新特性需要配置单独的加载bebblle-loader 等。

"devDependencies": {
    "webpack": "^5.76.3",  // 打包工具
    "webpack-cli": "^5.0.1",  // 构建打包依赖项目=
    "webpack-dev-server": "^4.13.1", // 热更新预览
}

webpack的模块加载,支持一下模块化标准:

webpack 配置介绍_第1张图片

但是在项目使用过程中,不建议混合使用,会增加维护难度。

二、loader

        loader 是一个管道,Webpack 可以对同一资源使用多个loader,每个loader 返回一个 js 对象,传到另一个 loader。

1、loader 的分类

  • 编译转换类
  • 文件操作类
  • 代码检查类

2、loader 的配置方式

  • 配置文件中声明:在webpack.config.js中声明
  • 内联方式:在每个import语句中指定loader
  • cli方式:在shell命令中指定
babel-loader 将Es6+ 语法转换为Es5
babel-core loader的核心依赖
babel-preset-env 兼容最新的语法,不用担心浏览器兼容,同时让打包更小,以及es2015的babel
babel-preset-react 支持jsx语法
css-loader 用于识别.css文件, 处理css必须配合style-loader共同使用,只安装css-loader样式不会生效。
style-loader 用于将css编译完成的样式,挂载到页面style标签上。
file-loader 把文件、图片等输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
url-loader 和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
sass-loader css预处理器,我们在项目开发中经常会使用到的
postcss-loader 用于补充css样式各种浏览器内核前缀
ts-loader 用于配置项目typescript
html-loader 我们有时候想引入一个html页面代码片段赋值给DOM元素内容使用,这时就用到html-loader,建议安装低版本,高版本可能会不兼容导致报错。
eslint-loader 用于检查代码是否符合规范,是否存在语法错误。
vue-loader 用于编译.vue文件,如我们自己搭建vue项目就可以使用vue-loader

3、插件

例如:清除上次结果的目录,拷贝资源文件,压缩代码等。

表头 表头
html-webpack-plugin 生成 html文件。原因:打包产物是 js,不包含 html,发布的时候比较麻烦,另外 html 引用打包后的 css 、图片,引用等内容路径可能找不到。默认生成index. html,可以使用filename指定html 名称
html-webpack-plugin 清理生成的打包目录
copy-webpack-plugin 复制静态文件。接受一个数组,数组元素是需要拷贝的路径,路径 可以是一个通配符。
DefinePlugin 内置插件。注入全局变量的插件,通常使用该插件来判别代码运行的环境变量
minCssExcractPluin 提取打包的 css 文件,实现 css 加载
optimize-css-assets-webpack-plugin 压缩 css

三、React基本配置

1、.babelrc

{
  "presets": [
    "@babel/preset-env",
    [
      "@babel/preset-react",
      {
        "runtime": "automatic"
      }
    ],
    "@babel/preset-typescript"
  ]
}

2、webpack.config.js

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    mode: 'development',
    entry: './src/index',
    module: {
        rules: [
            {
                test: /\.(js|jsx|ts|tsx)$/,
                exclude: /node_modules/,
                loader: "babel-loader",
            },
            {
                test: /\.css$/,
                exclude: /node_modules/,
                use: [
                    {loader: 'style-loader'},
                    {loader: 'css-loader'},
                ]
            },
            {
                test: /\.(png|jpg|gif|svg)$/,
                exclude: /node_modules/,
                loader: 'file-loader',
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: "23",
            template: "public/index.html"
        }),
    ],
};

3、package

  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^9.1.2",
    "babel-preset-env": "^1.7.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "css-loader": "^6.7.3",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.5.0",
    "style-loader": "^3.3.2",
    "webpack": "^5.76.3",
    "webpack-cli": "^5.0.1",
    "webpack-dev-server": "^4.13.1"
  }

四、loader 和plugin区别

  • loader:在加载模块的缓解工作 plugin:webpack 的每一个环节。
  • plugin:通过勾子机制来实现的。在勾子上挂载任务。webpack要求插件必须是一个函数或者是一个包含apply方法的对象。

五、tree shaking

        webpack 在打包的时候将会剔除掉被没有被使用到的代码达到减小报体积,缩短 http 请求时间,起到一定效果的页面优化。在webpack5中已经自带tree-shaking功能,在打包模式为production时,默认开启 tree-shaking功能。需要注意的是他不是某一项功能配置的使用,而是一组功能搭配使用后的优化效果,在生产环境自动启动,其他模式下需要手动开启。

webpack.config.js:

optimization: {
    usedExports: true,    // 负责标记枯树叶
    minimize: true ,    // 负责摇掉枯树枝
    concatenateModules: true,   //尽可能将所有的模块合并输出到一个函数中,提升运行效率,减少了体积(Scope hoisting)
}

tree sharking vs babel:

        tree sharking的实现必须使用 ES Module,但是为了转换新特性,很多时候首页 babel-loader处理 js,处理的过程中可能使用@babel/preset-env将 ES Module转为 commonJs,这时候tree sharking就失效了。

webpack 配置介绍_第2张图片

 将 modules 改为 false 可以避免,在最新版本的 webpack5已经不存在这个问题了。

六、sideEffects

        sideEffects一般用于 NPM 包标记是否有副作用,和tree sharking没任何关系。

optimization: {
    sideEffects: true,
}
// 除此之外还需要在 package 里面配置sideEffects
"sideEffects" : ["文件路径"], 或者 "sideEffects" : true

        该功能在打包模式为production时,默认开启,在打包时候回检测是否有标识,有副作用,没有副作用在打包时候不会参与打包。启动该功能时候需要确保没有副作用,否则的话会误删。

七、代码分包

        如果应用很复杂,打包的bundle 会非常大,导致卡顿,需要分包,按需加载。可以分为多入口打包,一个页面一个入口,公共的抽取。

1、entry配置成一个对象

plugins: [
    new HtmlWebpackPlugin({
        title: "标题1",
        template: "./src/index.html",
        filename: "index.html",
        chunks: ['index']  // 需要配置chunks
    }),
    new HtmlWebpackPlugin({
        title: "标题2",
        template: "./src/album.html",
        filename: "album.html",
        chunks: ['album']  // 需要配置chunks
    }),
],
// 这块是数组,而不是单一入口的文件
entry: {
    index: './src/index.js',
    album: './src/album.js',
},
output: {
    filename: "[name].bundle.js"  // name会被替换成入口的名称
}

公共模块抽取:

splitChunks: {
    chunks: "all" // 表示将所有的公共模块都提取到单独的bundle.js 中
}

2、webpack-merge

        development(开发环境) 和 production(生产环境) 这两个环境下的构建目标存在着巨大差异,通过 webpack-merge 可以将基础的配置抽象到 webpack.base.js 中,开发环境和线上环境分别使用 webpack.dev.js 和 webpack.prod.js,然后 merge(webpack.base.js)即可。

八、动态加载

        动态导入会被自动的分包,相比多入口的方式,动态导入更加灵活。通过ES Module 的方式:

if (hash === 'album') {
    import(/* webpackChunkName : album*/,'./src/album').then(module => {

    })
} else {
    import(/* webpackChunkName : index*/,'./src/index').then(module => {

    })
}

        webpackChunkName:给分包起名字,如果名称相同,则打包时候会被打包在一起。

九、css 提取和压缩

1、css 提取

minCssExcractPluin:提取 css 模块,按需加载 css。当超过150KB 建议使用。

module: {
    rules: [
        {
            test: /\.css$/,
            exclude: /node_modules/,
            use: [
                {loader: MinCssExcractPluin.loader},
                {loader: 'css-loader'},
            ]
        }
    ]
},
plugins: [
    new MinCssExcractPluin()
],

2、css压缩

        webpack 在生产模式下内置插件默认只针对于 js 压缩,对于其他文件的压缩需要借助于插件。css 压缩需要用到optimize-css-assets-webpack-plugin,需要注意的是OptimizeCSSAssetsPlugin需要配置在optimization里面,因为配置在plugins针对于全部生效,而配置在optimization里面:

optimization: {
    minimizer: [
        new OptimizeCSSAssetsPlugin(), // 设置该内容后回覆盖系统的 js 压缩插件,导致js 不能被压缩,需要在这再次配置下默认的 js 压缩插件terser-webpack-plugin
        new TerserPlugin()
    ]
}

十、输出文件名称 hash

1、hash:普通 hash全局生效

output: {
    filename: "[name]-[hash].bundle.js"  // name会被替换成入口的名称
},
plugins: [
    new MinCssExcractPluin({
        filename:  "[name]-[hash].bundle.css"
    })
],

2、contenthash:文件 hash,根据文件生成

output: {
    filename: "[name]-[contenthash].bundle.js"  // name会被替换成入口的名称
},
plugins: [
    new MinCssExcractPluin({
        filename:  "[name]-[contenthash].bundle.css"
    })
],

还可以指定缓存的hash 的长度,如下8表示 hash 的长度:

filename:  "[name]-[contenthash:8].bundle.css"

十一、sourceMap

        解决在编译后代码和源代码不一致引发的调试困难问题。source-map是从已转换的代码,映射到原始的源文件,使浏览器可以重构原始源并在调试器中显示重建的原始源。在 webpack.config.js配置。支持很多种sourceMap,调试效果和打包效率都不一样。常见的如下:

1、eval
每个module会封装到 eval 里包裹起来执行,并且会在末尾追加注释 //@ sourceURL.

2、source-map
生成一个SourceMap文件.

3、hidden-source-map
和 source-map 一样,但不会在 bundle 末尾追加注释.

4、inline-source-map
生成一个 DataUrl 形式的 SourceMap 文件.

5、eval-source-map
每个module会通过eval()来执行,并且生成一个DataUrl形式的SourceMap.

6、cheap-source-map
生成一个没有列信息(column-mappings)的SourceMaps文件,不包含loader的 sourcemap(譬如 babel 的 sourcemap)

7、cheap-module-source-map
生成一个没有列信息(column-mappings)的SourceMaps文件,同时 loader 的 sourcemap 也被简化为只包含对应行的。

你可能感兴趣的:(前端,webpack,前端,node.js)