Administrator
发布于 2022-10-29 / 35 阅读 / 0 评论 / 0 点赞

webpack配置2022

webpack配置

webpack 是代码编译工具,有入口、出口、loader 和插件。webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle
image-1667055108897
同时还发现导入了很多个JS的文件
image-1667055119186
这就是我们之前做项目的时候所导入的依赖包,这么做有什么问题没有?
image-1667055125685

首先要知道 webpack就是打包工具,它可以将我们的所用到的资源进行合理的整合,它相当于一个项目经理,合理的整和资源 ,分配资源,最后生成资源

常用的打包工具

就目前来说,打包工具不仅仅只有webpack还有其它的一些,我们现在认识一下常用的打包工具

  1. webpack这一个是2022之前非常火的一个打包工具,目前最新的版本已经到5了,它使用起来非常方便,并且功能强大,后期的vue、react,angular,sevlte都会使用它
  2. grunt打包工具,Grunt 是一个基于任务的JavaScript工程命令行构建工具。它了是第一代构建工具,目前基本上已经被淘汰了,不再使用了,它所实现的功能与webpack相似
  3. gulp打包工具,gulp 将开发流程中让人痛苦或耗时的任务自动化,从而减少你所浪费的时间、创造更大价值。这个东西本来应该也过时了,但是现在又活过了,后期面有一个叫vite的打包工具借鉴它的思路形成了另一个工具
  4. vite打包工具,vite是下一代前端开发与构建工具。 [1]  Vite意在提供开箱即用的配置,同时它的插件API和JavaScript API 带来了高度的可扩展性,并有完整的类型支持。【我们后面就主要去使用它了,就不再去使用webpack了】
    vite是唯一的一款国产打包工具,好用,文档齐全,并且与vue实现高度整合,无需任何配置就可以实现vue的脚手架
    上面所有的打包工具都有一些共同的特征,所有的打包工具应该都有配置文件 ,并且配置文件里面必须有四个部分

webpack打包工具的核心点

https://webpack.docschina.org/

  1. 入口
  2. 出口
  3. loader
  4. 插件plugins

目前所存在的问题

Person.js

class Person {
    constructor(userName) {
        this.userName = userName;
    }
    sayHello() {
        setTimeout(() => {
            console.log(`大家好,我叫${this.userName}`);
        }, 1000);
    }
}
//现在用的是ESModule,不是CommonJS模块
export default Person;

Student.js

import Person from "./Person.js";
class Student extends Person{
    constructor(userName,sex){
        super(userName)
        this.sex = sex;
    }
    study(){
        console.log(`${this.sex}学生在学习`);
    }
}
export default Student;

index.js

import Student from "./Student.js";
let s = new Student("张珊","女");
s.sayHello();
s.study();

当我们把所有的js文件写好了以后,我们在index.html的网页里去调用

<script src="js/index.js" type="module"></script>

我们现清楚的看到了这个代码的运行

表面上看是没有任何问题

  1. 因为我们现在使用的是ESModule的方式在使用模块化,所以在script的标签上面,我们使用了type="module"这个属性,但是这个属性它是在新版本的浏览器里才支持,旧版本是不支持,所以会有兼容性
  2. 我们在js里面大量使用了class,extends以及箭头函数等ES6的语法,但是这些语法也是有兼容性的,在低版本的浏览器里面,ES6是不被支持的
  3. 现在我们打开的网页是以http协议打开 的,当我们双击文件直接打开的时候,这个时候就会报错了
    上面的三个问题就是目前所存在的问题,如果想解决上面的问题,我们可以直接使用webapck打包个,生成一个新的文件就可以了

webapck工具的安装

webpack是nodejs平台下面的一个包,我们可以直接通过npm来进行安装

$ npm install webpack webpack-cli --save-dev

webpack的配置文件

webpack只是一个工具,它需要参照一定的规则来处理事情,这个规则就是配置文件,它的配置文件是固定格式,具体可以参考它的官方文档
概念 | webpack 中文文档 (docschina.org)
我们在当前的项目下面新建一个webpack.config.js的文件 ,然后配置如下

const path = require("path");
/**
 * @type {import("webpack").Configuration}
 */
const config = {
    // 入口
    entry: "./js/index.js",
    // 出口
    output: {
        path: path.join(__dirname, "./dist"),
        filename: "bundle.js"
    }
    //loader
    //插件
}
module.exports = config;

当我们把配置文件写好了以后,我们就可以启动webpack的打包工具,然后开始打包,在打包之前我们还要知道怎么样启动webpack

webpack的启动

package.json下面的scripts目录配置启动命令

"scripts": {
	"test": "echo \"Error: no test specified\" && exit 1",
	"build": "webpack --config ./webpack.config.js"
},

现在我们就来启动一下刚刚配置的命令

$ npm run build

使用babel插件来处理JS的兼容性

image-1667055154562
它是webpack的一个插件,作用就是将ES6的代码转换成兼容性比较高的ES5代码

在这之前我们使用webpack进行打包的时候,我们都发现我们的JS代码虽然完成了打包合并 ,但是最大的问题它没有提高兼容性,仍然是ES6的代码,如果这些代码要是在浏览器里面运行很可能会有兼容性的问题
image-1667055160906
在设置这一页里面,我们可以找到webpack 的配置

第一步:安装babel的需要的依赖包

npm install --save-dev babel-loader @babel/core

第二步:配置webpack中的babel插件

//省略部分代码......
module: {
        //你在import的时候会导入不同的文件 ,我们要根据不同的文件来制定不同的规则
        rules:[
            {
                //如果我在import的时候发现你的后缀名是.js的文件,那么我就要使用babel去转换一下,
                //将你转换成es5的代码
                test:/\.js$/,
                exclude: /node_modules/,exclude: /node_modules/,
                // use:["babel-loader"]
                use:[
                    {
                        loader:"babel-loader"
                    }
                ]

            }
        ]
    },

第三步:指定babel的转换规则
image-1667055169410
在上面的截图里面,我们可以看到它使用了@babel/preset-env的规则,这个规则是根据你所配置的环境来决定转换规则

环境也就是开发环境,就是根据我们自己的开发环境来决定怎么转换

它提示我们需要安装一个包,那么我们现在就安装

$ yarn add @babel/preset-env --dev

当包安装完成以后,我们可以在刚刚创建的配置文件里面写入转换规则了

再我们再次去启动的时候,我们发现仍然没有执行转换规则 ,这是为什么呢?因为我们还指定JS的运行环境
在设置preset的时候,我们需要第三方的插件,分别是下面三个包

  1. @babel/preset-env这个包的作用是环境配置环境来决定怎么样转换JS代码
  2. @babel/polyfill这个包主要的作用就是实现ES6中的一些扩展功能,如Map,Set,Symbol
  3. core-js这个包主要的作用就是用于实现Generater function生成器函数的功能,以及async/await/Promise
$ yarn add @babel/polyfill core-js --dev
{
    "presets": [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage",
                "corejs": "3",
                "targets": {
                    "browsers": [
                        "last 2 version",
                        "> 1%",
                        "not dead",
                        "ie 8"
                    ]
                }
            }
        ]
    ]
}

代码说明:

  1. useBuiltIns我们的预设里面有很多转换规则,usage需要哪些就使用哪些
  2. corejs后面的3代表的是当前安装的版本是多少
  3. targets这个指js转换以后的目标平台 ,我们看到这里是browsers代表js在浏览器里面运行,后面有一个数组
  • last 2 version代表要支持到浏览的的最后2个版本
  • > 1%浏览器的使用市份额大于1%就可以了
  • not dead 没有死的浏览器都支持

当然 们把所有的东西都弄完了以后,最后在webpack.config.js的配置文件上面添加如下代码就可以实现最终的ES6转ES5了

const config = {
	target:["web","es5"]
}

配置html-webpack-plugin

这个插件的作用就是帮助我们在这个地方将生成好的JS与CSS插入到HTML文件当中去
安装这个插件

$ yarn add html-webpack-plugin --dev

配置html-webpack-plugin插件

//插件
    plugins: [
        new HTMLWebpackPlugin({
            // 源文件
            template: path.join(__dirname, "index.html"),
            // 生成的目标文件的名称
            filename: "index.html",
            // 把打包的js文件或后期的css文件也通过标签链接进去
            inject: true
        })
    ]

配置Clean-Webpack-Plugin

在刚刚的代码里面,我们可以看到,我们每次生成的东西都会在dist的目录下面,但是有些文件我们是不需要的,所以我们希望在每次生成的时候都将目标目录dist清空,这个时候就需要使用Clean-Webpack-Plugin
安装

$ yarn add clean-webpack-plugin --dev

配置插件

const { CleanWebpackPlugin } = require("clean-webpack-plugin");
//配置文件 
plugins:[
	//省略部分代码
	 new CleanWebpackPlugin()
]

上面的插件在webpack5里面已经被自带了

const config= {
	//省略部分代码
	output:{
		clean:true
	}
}

webpack处理CSS文件

image-1667055186929
首先要弄清楚 一个问题,webpack只能够处理js,但是我们可以通过不同的loader来让wepback加载不同的文件
当我们向js文件里面导入一个css的时候文件,如下所示

import "../css/index.css";

这个时候再去编译我们就会报错
image-1667055195308
它提示我们需要一个loader去处理这样类似于css的文件
安装第三方loader

$ yarn add css-loader style-loader --dev
  • 第一个css-loader代表可以让webpack处理以css结尾的文件
  • style-loader可以让导入的css的样式文件以<style>标签的形式插入到网页当中

配置loader

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

配置postcss处理兼容性

安装

$ yarn add postcss-loader --dev

配置postcss-loader

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

当我们去配置好postcss-loader以后应该是不会生效的,因为我们还没有指定转换规则
指定转换规则
在指定转换规则的时候 ,我们要安装postcss的插件,它常用的插件有三个

  1. postcss-import
  2. postcss-cssnext
  3. cssnano
$ yarn add postcss-import postcss-cssnext cssnano --dev

然后再当前项目下面创建一个postcss.config.js的文件,去配置插件

//这里就是postcss的配置文件
module.exports = {
    plugins: [
        require("postcss-import"),
        require("postcss-cssnext"),
        require("cssnano")
    ]
}

当配置完成以后,我们还要在package.json里面去配置它们的转换规则

"browserslist": [
	"last 2 version",
	"> 1%",
	"ie 6"
]

如果在编译的时候报true is not Postcss Plugin是因为postcss的版本过低,我们要手动的提升版本

$ yarn add postcss@8  --dev

CSS文件分离

当我们处理好CSS的兼容性以后,我们发现我们的CSS代码是在JS里面的,我们要将CSS的代码从JS里面的分离出来
如果我们要分离CSS,又要使用一个包,这外叫叫mini-css-extract-plugin
安装

$ yarn add mini-css-extract-plugin --dev

配置这个包

const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
//压缩CSS,并分离CSS为一个单独的文件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

/**
 * @type {import("webpack").Configuration}
 */
const config = {
    target: ["web", "es5"],
    mode: "development",
    // 入口
    entry: "./js/index.js",
    // 出口
    output: {
        path: path.join(__dirname, "./dist"),
        filename: "js/bundle.[hash:8].js",
        publicPath: "./"
        // 自带的清除
        // clean:true
    },
    //模块,也就是加载器loader,当你去import一个文件时候 就会触发这个module里面的loader
    module: {
        //你在import的时候会导入不同的文件 ,我们要根据不同的文件来制定不同的规则
        rules: [
            {
                //如果我在import的时候发现你的后缀名是.js的文件,那么我就要使用babel去转换一下,
                //将你转换成es5的代码
                test: /\.js$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: "babel-loader"
                    }
                ]
            }, {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: "css-loader",
                        options: {
                            importLoaders: 1
                        }
                    },
                    "postcss-loader"
                ]
            }
        ]
    },
    //插件
    plugins: [
        new HTMLWebpackPlugin({
            // 源文件
            template: path.join(__dirname, "index.html"),
            // 生成的目标文件的名称
            filename: "index.html",
            // 把打包的js文件或后期的css文件也通过标签链接进去
            inject: true
        }),
        new CleanWebpackPlugin(),
        //配置CSS的分离插件
        new MiniCssExtractPlugin({
            filename: "css/index.[hash:8].css",
            ignoreOrder: false
        })
    ]
}

module.exports = config;

const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
//压缩CSS,并分离CSS为一个单独的文件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

/**
 * @type {import("webpack").Configuration}
 */
const config = {
    target: ["web", "es5"],
    mode: "development",
    // 入口
    entry: "./js/index.js",
    // 出口
    output: {
        path: path.join(__dirname, "./dist"),
        filename: "js/bundle.[hash:8].js",
        publicPath: "./"
        // 自带的清除
        // clean:true
    },
    //模块,也就是加载器loader,当你去import一个文件时候 就会触发这个module里面的loader
    module: {
        //你在import的时候会导入不同的文件 ,我们要根据不同的文件来制定不同的规则
        rules: [
            {
                //如果我在import的时候发现你的后缀名是.js的文件,那么我就要使用babel去转换一下,
                //将你转换成es5的代码
                test: /\.js$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: "babel-loader"
                    }
                ]
            }, {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: "css-loader",
                        options: {
                            importLoaders: 1
                        }
                    },
                    "postcss-loader"
                ]
            }
        ]
    },
    //插件
    plugins: [
        new HTMLWebpackPlugin({
            // 源文件
            template: path.join(__dirname, "index.html"),
            // 生成的目标文件的名称
            filename: "index.html",
            // 把打包的js文件或后期的css文件也通过标签链接进去
            inject: true
        }),
        new CleanWebpackPlugin(),
        //配置CSS的分离插件
        new MiniCssExtractPlugin({
            filename: "css/index.[hash:8].css",
            ignoreOrder: false
        })
    ]
}

module.exports = config;

配置sass的loader

sass的编译是依赖于第三方的环境,所以我们需要安装第三方的包

$ yarn add sass sass-loader --dev

配置sass-loader

,{
	test:/\.s[ca]ss$/,
	use:[
		MiniCssExtractPlugin.loader,
		{
			loader:"css-loader",
			options:{
				importLoaders: 2
			}
		},
		"postcss-loader",
		"sass-loader"
	]
}

webpack处理图片

在webpack里面,如果我们在css里面引入了图片以后,这个时候就会出山现问题,如下所示

.box {
    width: 200px;
    height: 200px;
    border: 2px solid black;
    display: flex;
    justify-content: center;
    align-items: center;
    transform: rotateZ(45deg);
    opacity: 0.4;
    background-color: deeppink;
    background-image: url("../img/dijia.jpg");
}

我们在这个地方使用了background-image的属性,它使用了一个文件 ,这个时候我们再去执行yarn run build的时候就会报错,原因就是因为webpack不能实现图片的加载【默认情况下webpack只能加载js文件,如果要加载其它的文件就需要有相应的loader来实现】

现在我们就需要使用2个loader 来处理文件的加载

安装

$ yarn add url-loader file-loader --dev

上面所安装的2个loader就是用于加载文件的,我们现在在webpack.config.js里面去配置一下

 {
    test: /\.(jpe?g|png|svg|bmp|gif)$/,
    use: [
        {
            loader: "url-loader",
            options: {
                limit: 8 * 1024,
                name: "[name].[hash:8].[ext]",
                outputPath: "img/",
                esModule: false,
            }
        }
    ],
    type: "javascript/auto"
},

上面的配置就是用于处理图片的,但是这个时候还要注意,如果我们这个时候直接进行打包,图片仍然是不能显示的,效果如下所示

image-1667055489971

我们可以看到,这个时候虽然已经生成了图片,但是背景图片没有显示,这是为什么呢?

我们再去看看生成的文件的结构

image-1667055535720

这个时候我们可以看到,生成的css与图片img并不在同目录下面,所以在background-image里面直接使用url("./img")是找不到这个img目录的,应该使用../img才可以找到这个目录

这个问题应该怎么解决呢

解决这个问题的方法有2处

第一种,在mini-css-extract-plugin里面配置,如下所示

image-1667055670407

在原来配置MiniCssExtractPlugin的地方指定一个publicPath的属性,让分离出来的的CSS的里面的路由前面都加上../。这样就可以了,我们现在去看一下效果

image-1667055787940

这个时候我们可以看到,图片已经正常显示了,因为背景图片的路径已经正常了

第二种解决方法

这一种解决方法与上面的相似,也是要配置publicPath,但是不是在MiniCssExtractPlugin这个插件上面配置,而是在url-loader这个插件上面配置,如下所示

image-1667055989224

这个时候我们可以看到效果如下图所示

image-1667056011787

webpack处理字体

在使用CSS的时候,我们有时候也会使用第三方的字体,如iconfont图标字体,如一些第三方的文字的字体,我们可以通过 @font-face来引自,这个处理过程与处理图片原理是一样的,仍然是使用url-laoderfile-loader是一样的,配置如下

{
    test: /\.(ttf|eot|woff|woff2)$/,
    use: [
        {
            loader: "url-loader",
            options: {
                limit: 8 * 1024,
                name: "[name].[hash:8].[ext]",
                outputPath: "fonts/",
                esModule: false,
                publicPath:"../fonts"
            }
        }
    ],
    type: "javascript/auto"
}

扩展yarn包管理工具

以前我们在安装第三方模块的时候我们使用的是npm来进行安装,但是这个东西并不是很完美,因为npm每次都要从服务器去下载包,这样做非常浪费流量,也非常耗时,所以我们要推荐第三方的包管理工具yarn
安装

$ npm install yarn -g

配置镜像地址
yarn每次去下载包的时候也是从国外的服务器下载的,我们仍然要配置国内的镜像地址

$ yarn config set registry https://registry.npmmirror.com

配置缓存的目录
因为yarn会缓存每一次下载过的包,它的缓存目录默认是在C盘,我们要将这个缓存的目录重新设置一下

$ yarn config set cache-folder D:\yarn_cache

yarn也是一个包管理工具,所以它也可以安装包,也可以卸载包,也可以生成依赖文件
yarn命令与npm命令的对比

npm命令 yarn命令
npm install 包名 yarn add 包名
npm uninstall 包名 yarn remove 包名
--save 不需要,它自动添加
--save-dev --dev
npm init yarn init
npm run 脚本 yarn run 脚本
npm install yarn

当我们如果需要清理缓存目录的时候 ,我们要使用下面的命令

$ yarn cache clean --force

评论