1.必备技能 – webpack学习之路

开发也有一段时间了,接触的东西越多,发现需要学习的内容也就越多,为了以后更好的工作(加薪),下定苦心学习前端神器(webpack)。下面,走起!!!

版本说明:

  • webpack v5.37.1
  • node v12.13.1

一、入门

1.1初始化项目

新建一个目录(我这里建的事my-webpack,之后也是用这个目录)

mkdir my-webpack
cd my-webpack
npm init

// 或者
mkdir my-webpack && cd my-webpack && npm init
复制代码

因webpack是需要node支持的,因此需要安装 webpackwebpack-cli 包。

npm i -D webpack webpack-cli
复制代码

说明:-D 为 –save-dev 的缩写,-S 为 –save 的缩写

新建一个 src 目录,该目录下新建 main.js 文件并输入测试代码

console.log("webapck学习")
复制代码

配置 package.json 文件

"scripts": {
    "build": "webpack ./src/main.js"
}
复制代码

新建 webpack.config.js 文件,并设置 mode 模式(可忽略,后期会在 build/ 目录下)

const isDev = false
module.exports = {
    mode: isDev ? 'development' : 'production'
}
复制代码

运行

npm run build
复制代码

此时,生成了 dist/main.js 文件,说明打包成功了。

1.2 配置自己的打包命令

上面我们使用的都是webpack默认的配置,下面来实现自己的配置。
首先新建 build 文件,然后新建 webpack.config.js 文件, 写入以下配置代码:

const path = require('path')
const isDev = false

module.exports = {
    mode: isDev ? 'development' : 'production', // 模式
    entry: path.resolve(__dirname, '../src/main.js'), // 入口
    output: {
        path: path.resolve(__dirname, '../dist'), // 打包后目录
        filename: 'build.js'
    }
}
复制代码

更改 package.json 打包文件

"scripts": {
    "build": "webpack --config build/webpack.config.js"
}
复制代码

然后执行 npm run build 就可以生成打包后的文件,其中 dist/build.js 文件就是主文件。

1.3 配置html模版

在实际开发中,或者vue开发者会发现打包之后生成的js文件每次都不一样,打包配置名称是通过哈希值来命名的

image.png

我们又不能每次都去更改html的引入,因此需要引入一个插件

npm i -D html-webpack-plugin
复制代码

配置打包文件

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

const isDev = true

module.exports = {
    mode: isDev ? 'development' : 'production', // 模式
    entry: path.resolve(__dirname, '../src/main.js'), // 入口
    output: {
        path: path.resolve(__dirname, '../dist'), // 打包后目录
        filename: '[name].[hash:8].js'
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../public/index.html')
        })
    ]
}
复制代码

在根目录下新建 public/idnex.html 目录和文件,代码实现如图所示:

image.png

然后执行打包命令,就可以生成打包文件了,可以看出js已经引入了

image.png

1.3.1 多文件入口

有的时候我们会遇到前端入口和管理端入口分别是两个文件,这个时候可以使用 html-webpack-plugin 来实现多入口文件打包

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

const isDev = true

module.exports = {
    mode: isDev ? 'development' : 'production', // 模式
    entry: {
        main: path.resolve(__dirname, '../src/main.js'),
        admin: path.resolve(__dirname, '../src/admin.js'),
    },
    output: {
        path: path.resolve(__dirname, '../dist'), // 打包后目录
        filename: '[name].[hash:8].js'
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../public/index.html'),
            filename: 'index.html',
            chunks: ['main'] // 与入口文件对应的模块名
        }),
        new HtmlWebpackPlugin({ 
            template: path.resolve(__dirname, '../public/admin.html'),
            filename: 'admin.html',
            chunks: ['admin'] // 与入口文件对应的模块名
        })
    ]
}
复制代码

执行npm run build 会生成以下目录

image.png

1.3.2 清理缓存

我们在多次使用 npm run build 打包之后,会发现dist文件中会存在过期的缓存文件,这个时候手动清除会比较困难和繁琐。因此,推荐一个打包之前清除缓存的插件 clean-webpack-plugin

const {
    CleanWebpackPlugin
} = require('clean-webpack-plugin')
module.exports = {
    // ...
    plugins: [new CleanWebpackPlugin()]
}
复制代码

1.4 引入css

js 是我们的入口文件,因此在main.js 中引入css

// src/main.js
import "./assets/index.css"
import "./assets/style.less"
import "./assets/style.scss"
console.log('webpack学习-main')
复制代码

同时也需要插件 style-loadercss-loader 来解析css文件

npm i -D style-loader css-loader
复制代码

如果你是使用 lessscss 来构建样式

npm i -D less less-loader
npm i -D node-sass sass-loader
复制代码

配置文件如下:

// webpack.config.js

module.exports = {
    // ...
    module: {
        rules: [{
            test: /\.css$/,
            use: ['style-loader', 'css-loader'] // 从右向左解析原则
        }, {
            test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader'] // 从右向左解析原则
        }, {
            test: /\.scss$/,
            use: ['style-loader', 'css-loader', 'sass-loader'] // 从右向左解析原则
        }]
    },
}
复制代码

打包后打开 html 查看元素如下:
image.png

1.4.1 为css添加浏览器前缀(浏览器兼容处理)

浏览器的兼容问题可以说是让人头疼的一件事情,而使用 postcss-loaderautoprefixer loader之后,这些问题就不需要我们再去考虑啦。

npm i -D postcss-loader autoprefixer  
复制代码

在配置中引入:

// webpack.config.js

module.exports = {
    // ...
    module:{
        rules:[
            {
                test:/\.less$/,
                use:['style-loader','css-loader','postcss-loader','less-loader']
           }
        ]
    }
} 

复制代码

接下来,我们还需要引入 autoprefixer 来使其生效,这里有两种方法:
1.在根目录下新建 postcss.config.js 文件,并写入以下内容:

module.exports = {
    plugins: [require('autoprefixer')]
}
复制代码

2.在 webpack.config.js 文件中配置

// webpack.config.js

module.exports = {
    // ...
    module:{
        rules:[{
            test:/\.less$/,
            use:['style-loader','css-loader',{
                loader:'postcss-loader',
                options:{
                    plugins:[require('autoprefixer')]
                }
            },'less-loader']
        }]
    }
}
复制代码

运行打包之后发现,style 样式已经全部加载到了 html 页面中,我们发现如果样式比较多的话,页面会显得非常杂乱。因此,我们需要将 css 样式进行拆分。

1.4.2 拆分css

我们使用 mini-css-extract-plugin 来实现 css 拆分

npm i -D mini-css-extract-plugin
复制代码

说明:webpack4.0之前我们使用 extract-text-webpack-plugin 插件, webpack4.0之后我们使用 mini-css-extract-plugin 插件

在配置中使用

// webpack.config.js

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
           MiniCssExtractPlugin.loader,
           // 'style-loader', // 此处需要删除,否则会报错
           'css-loader',
        ],
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
        filename: "[name].[hash].css",
        chunkFilename: "[id].css",
    })
  ]
}
复制代码

效果如下:

image.png

1.4.3 拆分多个css(webpack5.0忽略)

我们上面介绍了 mini-css-extract-plugin 的使用,但是该插件目前只能生成一个文件,想要实现拆分成多个css文件,我们需要引入 extract-text-webpack-plugin@next 插件。

需要说明的是,extract-text-webpack-plugin@next 只能在webpack5.0以下使用。

安装插件

npm i -D extract-text-webpack-plugin@next
复制代码

配置文件

// webpack.config.js

const path = require('path');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')
let indexLess = new ExtractTextWebpackPlugin('index.less');
let indexCss = new ExtractTextWebpackPlugin('index.css');

module.exports = {
    // ...
    module:{
      rules:[
        {
          test:/\.css$/,
          use: indexCss.extract({
            use: ['css-loader']
          })
        },
        {
          test:/\.less$/,
          use: indexLess.extract({
            use: ['css-loader','less-loader']
          })
        }
      ]
    },
    plugins:[
      indexLess,
      indexCss
    ]
}
复制代码

1.5 打包字体、图片、媒体等文件

上面我们将样式进行了打包处理,同时我们还需要将字体、图片、媒体等文件也进行打包处理,这时候我们用到 file-loader 插件,将文件输出到对应的目录中。

说到 file-loader ,我们还配合一个伴生插件 url-loader 来使用,如更文件小于限制的大小,返回base64编码,否则将文件移动到输出的目录下。

安装插件

npm i -D file-loader url-loader
复制代码

配置文件如下:

// webpack.config.js

module.exports = {
    // ...
    module: {
        rules: [
            // 图片文件
            {
                test: /\.(jpe?g | png | gif)/i,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 10240,
                        fallback: {
                            loader: 'file-loader',
                            options: {
                                name: 'img/[name].[hash:8].[ext]'
                            }
                        }
                    }
                }]
            },
            // 媒体文件
            {
                test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 10240,
                        fallback: {
                            loader: 'file-loader',
                            options: {
                                name: 'media/[name].[hash:8].[ext]'
                            }
                        }
                    }
                }]
            },
            // 字体文件
            {
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 10240,
                        fallback: {
                            loader: 'file-loader',
                            options: {
                                name: 'fonts/[name].[hash:8].[ext]'
                            }
                        }
                    }
                }]
            },
        ]
    }
}
复制代码

1.6 用babel转义js文件

为了js能够兼容更多的环境,需要安装以下插件

npm i -D babel-loader @babel/preset-env @babel/core
复制代码

注意:babel-loader@babel/core 版本的对应关系

  • babel-loader 8.x 对应 @babel/core 7.x
  • babel-loader 7.x 对应 @babel/core 6.x

配置文件如下:

// webpack.config.js

module.exports = {
    // ...
    module:{
        rules:[
          {
            test:/\.js$/,
            use:{
              loader:'babel-loader',
              options:{
                presets:['@babel/preset-env']
              }
            },
            exclude:/node_modules/
          },
       ]
    }
}
复制代码

babel-loader 是只能将 ES6/7/8 转化成 ES5 语法,但是对于新的 API 是不做转换的(promise、Generator、Set、Maps、Proxy等)。因此,我们需要使用 @babel/polyfill 插件来解决这个问题。

npm i -D @babel/polyfill
复制代码

配置文件如下:

// webpack.config.js

const path = require('path')
module.exports = {
    entry: ["@babel/polyfill",path.resolve(__dirname,'../src/index.js')],
}
复制代码

以上,我们将 webpack 的基础用法过了一遍,但是想要熟悉运用到实际开发中,还需要进行实战。下面让我们一起摆脱脚手架尝试自己搭建一个vue开发环境。

常用包整理

  • webpack webpack工具
  • webpack-cli webpack脚手架
  • html-webpack-plugin 将打包生成的 js 动态引入到 html 中,同时也可以实现多文件入口
  • clean-webpack-plugin 每次打包之前清除 dist 下的缓存文件
  • style-loadercss-loader 解析css文件
  • lessless-loader 将 .less 结尾的文件解析成 css 文件
  • node-sasssass-loader 将 .scss 结尾的文件解析成 css 文件
  • postcss-loaderautoprefixer 给css样式添加前缀(浏览器兼容性处理)
  • mini-css-extract-plugin 将样式拆分成一个文件,webpack5.0 官方推荐使用
  • extract-text-webpack-plugin 将样式拆分成一个或多个文件,只支持webpack4.0及一下版本
  • file-loader 将文件输出到打包文件中
  • url-loader 将文件输出到打包文件中,如更文件小于限制的大小,返回base64编码,否则将文件移动到输出的目录下。
  • babel-loader@babel/preset-env@babel/core@babel/polyfill 转义js文件,兼容更多的环境

说明

该篇内容是笔者学习 黄小虫-2020年了,再不会webpack敲得代码就不香了(近万字实战) 大神写的关于 webpack 从入门到项目应用的学习记录。内容文本有摘抄,但全部代码笔者都已实现,在此记录,供更多人学习以及后期笔者回顾,谢谢您的阅读。

参考文献:

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享