webpack常用配置

78 阅读5分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

1.webpack入门概念

webpack是一个静态模块打包工具

不是运行的时候打包,是代码打包好后在‘浏览器’运行,在代码运行前就进行一步处理,这中间的一步,也引出了webpack工程化的强大能力。 区别webpack和webpack-cli

在webpack4之前,这两个东西是合二为一的,4开始,webpack相当于干活的,而cli相当于发命令的

webpack不用全局下载,只需要局部下载即可

webpack正处于一个发展期,有很多不同的版本,如果都用一个版本,可能不能处理多个新旧不同的项目

npx webpack 使用局部webpack进行打包(手动敲命令,使用布局) , 也可以使用npm scripts运行的webpack命令默认先找局部的webpack(使用配置,默认使用局部)

webpack本身就能解析打包各种模块规范的js代码

包括es6 , CommonJs , AMD/requirejs , CMD/seajs

核心基本概念

**

1.模式mode   development/production(默认)
2.入口entry
3.输出output
4.加载器loader
5.插件plugin

10个常用配置

1.mode 2.entry 3.output 4.module 5.plugins 6.devtools 7.devSever 8.reslove 9.optimization 10.externals

相关依赖包

webpack webpack-cli webpack-dev-server webpack-merge cross-env css-loader style-loader postcss-loader less-loader stylus-loader sass-loader file-loader url-loader image-webpack-loader babel-loader vue-loader eslint-loader MiniCssExtractPlugin.loader thread-loader html-webpack-plugin clean-webpack-plugin@1.0.1 mini-css-extract-plugin optimize-css-assets-webpack-plugin copy-webpack-plugin terser-webpack-plugin add-asset-html-webpack-plugin webpack-bundle-analyzer webpack.ProgressPlugin webpack.HotModuleReplacementPlugin webpack.HashedModuleldsPlugin webpack.DllPlugin webpack.DllReferencePlugin new webpack.ProvidePlugin\

基本使用

热更行,打包指令,自动将打包文件插入到页面当中 webpack.config.js配置:

const path = require('path')
const HtmlWebpckPlugin = require('html-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
// 输入目录,输出绝对路径
function resolve(dir) {
    return path.resolve(__dirname,dir)
}
module.exports = {
    //模式
    mode:'production',
    //入口
    entry:resolve('src/index.js'),
    //出口
    output:{
        path:resolve('dist'),
        filename:'bundle.js'
    },
    //模块加载器
    module:{
        rules:[
        ]
    },
    //插件
    plugins:[
        //向页面中插入引入打包的js/css的代码
        new HtmlWebpckPlugin({
            template:'public/index.html'
        }),
        //清楚打包文件夹 (dist)
        new CleanWebpackPlugin(['dist'])
    ],
    //开发服务器
    devServer:{
        open:true,//自动打开浏览器访问
    }
}

package.json口令配置:
  "scripts": {
    "build": "webpack --mode production",   //  yarn build / npm run build
    "dev":"webpack-dev-server --mode development"  //yarn dev  / npm run dev
  },

js打包

主要使用babel进行对js的打包

webpack文档 => loader => babel

**

//1.对babel的理解
webpack本身有用处理各种模块化规范的能力,但是,并不具备处理es6语法的能力,
真正处理es6的是:babel
但是babel本身在某种意义上也不具备编译es6的能力,babel相当于提供了一个平台,babel依赖的非常多单独针对某个语法编译的插件,比如async就有一个babel的编译插件,const也有一个,箭头函数又有一个,而babel把他们汇集在一起。
意义何在?:
如此众多的插件,不可能每个都去配置,所以用以一个大包来汇总和众多小的插件


查看@babel/preset-env 下package.json 就可以查看到babel的众多依赖

//2.babel的解析
1.babel只转换不兼容的“新语法”(可以理解为语法糖,本质上还是底层的一些语法实现的)
=>const/let/箭头函数/解构赋值/class语法.... 

2.babel不转换新的api (理解为新的方法,浏览器本身就不存在,所以无法编译)
=>Promise/Map/Set/Object.assign()/Generator/Proxy ....

//3.引出@babel/polyfill : 可以理解为一个补丁包
既然babel不能编译新的api,那么就需要一个包将这些方法都实现,然后打入项目之中,供人使用
=>而@babel/polyfill主要依赖两个包
1.core-js:一个俄罗斯的小哥所写,主要重写了很多es6,es7..的语法
2.regenerator-runtime: 弥补core-js没有实现的async await的缺陷

更进一步的处理:

**

1.我们使用基础配置的babel进行es6语法的编译

2.使用 @babel/polyfill 进行es6新api进行编译
=》低版本浏览器语法,打包支持es6语法,通常是polyfill通过类似打补丁的方式将包引入到项目当中
=》既然有包打入项目,就可以进行优化
	1.使用配置的方式,实现按需引入,用了什么语法就打入什么补丁
    2.当使用有很多模块使用了类语法的时候,每个模块都会独立产生一个辅助函数=>_classCallCheck
	可以提取出来生成一次即可,就需要使用plugins:[@babel/plugin-transform-runtime] 

打包图片

主要用到的loader有:

  • file-loader
  • url-loader( 依赖于file-loader,针对小图片可以进行base64处理,减少请求)

有时候会出现url-loader的包依赖于file-loader但是却没有下载的情况,需要自行下载

**

webpack.config.js下module属性配置:
   //模块加载器
    module:{
        rules:[
            //处理图片
            {
                test:/.(png|jpg|gif|svg)$/,
                use:{
                    loader:'url-loader',
                    options:{
                        limit:1024*10, //把小于 5kb的文件转成Base64的格式
                        name:'img/[name].[ext]',
                    }
                }
            }
        ]
    }

还有图片压缩,自行搜索使用

出了图片,还有字体,音频同样使用的都是url-loader

**

使用方法和图片一样,直接添加一个对象配置即可,修改test属性和use的options属性

css处理

对于处理不同的css文件,需要不同的loader:
css:  1.css-loader  2.style-loader 
less:  1.less  2.less-loader
stylus:  1.stylus  2.stylus-loader 
sass:  1.node-sass  2.sass-loader //注意:node-sass下载可能失败,yarn < npm < cnpm

使用配置:

css全部被打包进bundle.js当中,css的样式都是通过js来写入的

**

webpack.config.jsmodule属性配置:
   //模块加载器
    module:{
        rules:[
            //处理css
            {
                test: /.css$/,
                use: ['style-loader', 'css-loader'] //从下往上,从右往左
            },
            //处理less
            {
                test: /.less$/,
                use: ['style-loader', 'css-loader', 'less-loader'] 
            },
            //处理stylus
            {
                test: /.(styl|stylus)$/,
                use: ['style-loader', 'css-loader', 'stylus-loader'] 
            }
        ]
    }

PostCss

利用PostCss可以:1.自动添加代码的厂商前缀 2.准换现代的css代码

主要包:autoprefixer  postcss-loader
配置:
webpack.config.jsmodule属性配置:
   //模块加载器
    module:{
        rules:[
            //处理css
            {
                test: /.css$/,
                use: ['style-loader', 'css-loader', 'postcss-loader'] //从下往上,从右往左
            },
            //处理less
            {
                test: /.less$/,
                use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'] 
            },
            //处理stylus
            {
                test: /.(styl|stylus)$/,
                use: ['style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] 
            }
        ]
    }

再创建postcss.config.js:
module.exports = {
    plugins:[
        require('autoprefiexer')(),
        require('postcss-px2rem')({
            unitRem:37.5
        })
    ]
}

单独打包css

要用上mini-css-extract-plugin    MiniCssExtractPlugin.loader

webpack.congfig.js:
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    module:{
        rules:[
            //处理css
            {
                test: /.css$/,
                use: [MiniCssExtractPlugin.loader, //代替style-css
                      'css-loader', 
                      'postcss-loader'] //从下往上,从右往左
            },
            //处理less
            {
                test: /.less$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader'] 
            },
            //处理stylus
            {
                test: /.(styl|stylus)$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'stylus-loader'] 
            }
        ]
    },
    plugins:[
        //从js中抽取css单独打包
        new MiniCssExtractPlugin({
            filename:'css/[name].css'
        })
    ]

注意:抽取文件单独打包的时候需要主要一些路径问题,此处会出现一个绝对路径的问题

解决:

**

    output:{
        path:resolve('dist'),
        filename:'bundle.js'
        publicPath:'/'      //给出口文件的路径设添加为/,设置为相对路径
    },