继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

webpack4配置笔记

慕村9548890
关注TA
已关注
手记 1102
粉丝 227
获赞 987

起步

之前我们使用webpack命令,只要安装webpack模块即可,现在还要再安装一个webpack-cli
先创建项目

npm init

安装webpack 和 webpack-cli

npm install webpack webpack-cli -D

零配置

根目录创建src文件,下面新增index.js文件,


webp


针对比较简单的项目,webpack会去找src下面的index.js文件, 然后编译到dist
命令打包

npx webpack --mode development

mode主要控制压不压缩,默认不传,当值为production时,会压缩文件


webp

基本配置

创建config文件,创建webpack.dev.js文件
入口配置、出口配置。需要注意的是:output里面的path必须是绝对路径

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

entry允许接受字符串,数组,对象
数组可以这么写,多个入口


webp


对象的写法


webp


修改packjson打包指令

webp

image.png


直接输入命令

npm run build

webp


报错了信息
当然解决很容易,只要用name(也就是entry里面的key)区别分文件名就行了:

const path = require('path')module.exports = {
    entry: {
        index:'./src/index.js',
        a:'./src/a.js'
    },
    output: {
        filename: '[name].bundle.[hash:5].js',
        path: path.join(__dirname, '../dist')
    }
}

也可以指定md5文件,写法如下:

        filename: '[name].bundle.[hash:5].js',

:s表示截取5位
执行打包指令,生成


webp

dev-server

不可能每次刷新页面都要重新打包的,最好内存帮我们编译好,实时刷新页面,故有了webpakc-dev-server模块
在根目录创建一个html文件,引入index.js


webp

image.png


安装webpack-dev-server

sudo npm install webpack-dev-server -D

webpack.dev.js 添加devServer

 devServer: {        contentBase: path.resolve(__dirname,'../dist'),
        host:'localhost',
        compress:true,
        port:8888,
    }

package.json 添加指令


webp

npm run server

本地部署服务

插件

列举一些常用的插件

clean-webpack-plugin

用来清理文件夹的,例如清理dist文件

HotModuleReplacementPlugin

这是webpack自带的,和devServer的hot参数配合使用。当然如果是配置在命令行--hot,则不需要加这个插件

html-webpack-plugin

在webpack配置中,我们可以将output的生成文件,加上md5,但这样一来,我们得手动改html文件,所以就有了html-webpack-plugin,它能够帮我们插入script及link标签。

purifycss-webpack

移除未使用的css

DefinePlugin

这也是webpack自身提供的插件。

比如我们有这个一个场景,测试环境用A地址,线上环境用B地址。那么我们就可以利用这个插件结合Node_ENV来实现,然后配多个scripts。

 plugins: [
        ...,        new webpack.DefinePlugin({
            __DEV__: process.env.NODE_ENV === 'development'
        }),
    ]

然后我们就可以在自己的业务代码中使用__DEV__这个变量了。

extract-text-webpack-plugin

安装时,得npm install extract-text-webpack-plugin@next,因为4.0.0版本目前处于beta。

用来抽取css,这个插件用法会放在loder里面说明,因为这个代码得和loader一起使用才行。

copy-webpack-plugin

用来拷贝静态文件

BannerPlugin

webpack自带的一个插件,用来给代码添加版权信息

ProvidePlugin

webpack自带的一个插件,自动加载模块,而不必到处 import 或 require 。

 plugins: [
        ...,        new webpack.ProvidePlugin({
           $: 'jquery',
        }),
    ]

loader

wepack最最核心的就是,将所有的资源给转成js文件,这些是需要不同的loader来进行处理的,比如说css-loader、babel-loader、file-loader等
loader对象大概是长下面这样的:


webp


有以下常见的key:

test (匹配规则)
use (数组,里面放一个个的loader,执行顺序从右到左)
exclude (排除什么文件夹)
css相关配置
以less为例的话,先要安装less、less-loader、css-loader、style-loader模块。

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

use数组中的每一项都可以改写成如下的形式:

{    loader: "style-loader",
    options: {}
}

面几个loader的作用依次为:less-loader将代码转成css、css-loader用于解析(可以用来做css-moudle、压缩等)、style-loader则将解析后的样式嵌入js代码。

到了生产环境,我们不可能还是style的形式,通常都会抽成一个css。这个就得借助于上面提到的extract-text-webpack-plugin插件

module.exports = {
    mode: "development",
    entry: {
        ...
    },
    output: {
        ...
    },    module: {
        rule: {
            {
                test: /\.less$/,
                use: ExtractTextWebpackPlugin.extract({
                    use: [                        "css-loader",                        "less-loader"
                    ]
                })
            }
        }
    }
    devServer:{
        ...
    },
    plugins: [
        ...,        new ExtractTextWebpackPlugin({
            filename: "css/index.css"
        })
    ]
}

注意上面没有style-loader了。

这样一来的话,就得写两个webpack配置了。如果想写成一个的话,就得写成这样的:


webp

html-withimg-loader

这个是指在html文件中有用到某张图片,该图片有在入口文件中被引用。

具体配置如下:

{    test: /\.html/,
    use: 'html-withimg-loader'},
{    test: /\.(png|gif|jpg)$/,
    use: [{
        loader: 'url-loader',
        options: {
            limit: 5,
            outputPath: 'images/'
        }
    }]
},
resolve

这个对象可以用来起别名、新增扩展后缀等功能。

module.exports = {
    mode: "development",
    entry: {
        ...
    },
    output: {
        ...
    },    module: {
        ...
    },
    resolve:{        // 别名
        alias:{            '指定的名称':path.resolve(__dirname,'文件路径')
        },        // 省略后缀名
        extensions:[' ','.js','.json','.css'],
        modules:['node_modules','lib'],        //mainFields:['./a.js'] // 默认package.json的main是文件的入口 可以更改
    },
    devServer:{
        ...
    },
    plugins: [
        ...
    ]
}

抽取公共代码

module.exports = {
    mode: "development",
    entry: {
        ...
    },
    output: {
        ...
    },    module: {
        ...
    },
    optimization:{
        splitChunks:{
            cacheGroups:{
                commons: {
                    chunks: 'initial',
                    name: 'commons',
                    minChunks: 2,
                    maxInitialRequests: 5,
                    minSize: 0
                },
                vendor:{ // 抽离第三插件
                    test:/node_modules/,
                    chunks:'initial',
                    name:'vendor',
                    priority:10
                }
            }
        }
    },
    resolve:{
        ...
    },
    devServer:{
        ...
    },
    plugins: [
        ...
    ]
}

当然这样改了之后,下面的htmlPlugin里面也要加上这两个才行:

webp


在掘金上有一篇文章是关于这个参数讲解的,大家可以看看:webpack4.0打包优化策略(三)


在webpack3的时候,我依旧记得有一个bug,对Webpack的hash稳定性的初步探索,就是业务改了之后,vendor.js的hash值也会变化。

然后上面的方式,我测试了是OK了,也就是说不需要再加入HashedModuleIdsPlugin
结语
由于时间匆忙,整理的有点乱,希望大家有好的意见多多提议! 谢谢



作者:水落斜阳
链接:https://www.jianshu.com/p/71b61fc83ecc


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP