likes
comments
collection
share

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

作者站长头像
站长
· 阅读数 16

一 认识Webpack

webpack 是一个用于现代 JavaScript 应用程序的 打包工具。

当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个依赖图,然后将项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,可以在浏览器上直接运行。在 webpack 看来, 前端的所有资源文件(js、json、css、img 、html...)都会作为模块处理。

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

(一) webpack的五大核心概念

1. 五大核心概念

webpack的五大核心概念:

  • Entry: 指示 webpack 从哪个文件开始打包 。
  • Output: 指示 webpack 打包完的文件输出到哪里去,如何命名等 。
  • Mode:模式,有生产模式 production 和开发模式 development 两种。
  • Loader: webpack 本身只能处理 js、json 等资源,其他资源需要借助 loader,Webpack 才能解析 。
  • Plugins: 扩展 webpack 的功能 ,如打包优化、压缩等。

2. 生产模式VS开发模式

生产模式VS开发模式

  • 生产模式 production(默认)

    • 生产模式是开发完成代码后,我们需要得到代码将来部署上线。这个模式下我们主要对代码进行优化,让其运行性能更好。优化主要从两个角度出发:

      • 优化代码运行性能
      • 优化代码打包速度
  • 开发模式 development

    • 开发模式顾名思义就是我们开发代码时使用的模式。这个模式下我们主要做两件事:

      • 编译代码,使浏览器能识别运行,开发时我们有样式资源、字体图标、图片资源、html 资源等,webpack 默认都不能处理这些资源,所以我们要加载配置来编译这些资源。
      • 代码质量检查,树立代码规范,提前检查代码的一些隐患,让代码运行时能更加健壮。提前检查代码规范和格式,统一团队编码风格,让代码更优雅美观。

(二) 总结

  • webapck是一个构建工具,是基于node的,电脑上必须安装node,node版本需要大于16
  • 打包器,是从入口开始,按照模块依赖进行打包,最终得到浏览器的可以识别的静态资源。
  • 从某种程度来说,webpack代表的是一种架构能力。

二 基础使用Webpack

(一) 搭建环境

1.创建一个文件夹

2.初始化一个配置文件

npm init -y

3.写入package.json所需要的依赖

  "devDependencies": {
    "@babel/core": "^7.18.5",
 "@babel/preset-env" : "^7.18.2" ,
    "@babel/preset-react": "^7.17.12",
    "autoprefixer": "^10.4.7",
    "axios": "^0.27.2",
 "babel-loader" : "^8.2.5" ,
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^6.7.1",
    "eslint": "^8.18.0",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-plugin-import": "^2.26.0",
    "eslint-webpack-plugin": "^3.1.1",
    "file-loader": "^6.2.0",
 "html-webpack-plugin" : "^5.5.0" ,
    "less": "^4.1.3",
    "less-loader": "^11.0.0",
    "mini-css-extract-plugin": "^2.6.1",
    "optimize-css-assets-webpack-plugin": "^6.0.1",
    "postcss": "^8.4.14",
    "postcss-loader": "^7.0.0",
    "postcss-preset-env": "^7.7.1",
    "sass": "^1.52.3",
    "sass-loader": "^13.0.0",
    "style-loader": "^3.3.1",
    "url-loader": "^4.1.1",
    "vue-loader": "^17.0.0",
    "vue-style-loader": "^4.1.3",
    "vue-template-compiler": "^2.6.14",
    "vue-template-loader": "^1.1.0",
 "webpack" : "^5.73.0" ,
    "webpack-bundle-analyzer": "^4.5.0",
 "webpack-cli" : "^4.10.0" ,
 "webpack-dev-server" : "^4.9.2" ,
    "webpack-merge": "^5.8.0"
  },
  "dependencies": {
    "vue": "^3.2.37",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  }

4.安装依赖

npm i

(二) 零配置打包

现在,就涉及webpack,webpack-cli。

  • webpack 是核心内容提供了很多的API,插件。
  • webpack-cli 是在运行 webpack命令时,所依赖的一个工具。
  • 本地安装的话,使用 npx 可以执行安装在本地的命令行可执行命令。
  • webpack版本是5.x版本
npx webpack
  1. 参数:指定模式打包、指定入口文件(直接写)、指定出口路径--output-path、指定出口文件名--output-filename

  2. 默认参数值:

    1. 入口文件:src/index.js
    2. 出口文件:dist/main.js
    3. 打包模式:production
# 将 src/index.js 打包至 dist/main.js  模式默认值:production
npx webpack

# 将 src/index.js 打包至 dist/main.js  模式指定为:development
npx webpack --mode development

# 将 src/one.js 打包至 dist/main.js
npx webpack ./src/one.js --mode development

# 将 src/one.js、two.js 打包至 dist/main.js
npx webpack ./src/one.js ./src/two.js --mode development

# 将 src/one.js 打包至 build/main.js
npx webpack ./src/one.js --output-path build --mode development

# 将 src/two.js 打包至 dist/index.js 
npx webpack ./src/two.js --output-filename index.js --mode development

# 将 src/one.jssrc/two.js 打包至 build/index.js 
npx webpack ./src/one.js ./src/two.js --output-path build --output-filename index.js --mode development

(三) 基础配置打包

1.在项目根目录创建webpack.config.js文件

2.配置模式mode、入口entry、出口output

模式mode、入口entry、出口output(路径path只能是绝对路径)

const path = require("path")

module.exports = {
  mode: "development", // 开发打包
  // 入口
  // entry: "./src/main.js",
  // entry: path.resolve(__dirname, "src/main.js"), 
  entry: {
    // app表示你打包后的资源名字就是app
    app: path.resolve(__dirname, "src/main.js"),  // 绝对路径
  },
  // 出口
  output : {
    path: path.resolve(__dirname, "dist"),  // 绝对路径
    // filename:"bundle.js"  // 一捆  一束
    filename: "js/[name].[chunkhash:8].js",  // 一捆  一束
 //每次打包时自动删除之前的打包文件
 clean : true
}
}

3.配置开发服务器并使用其打包

到目前为止 webpack 基本上可以正常使用了,但在实际开发中你可能会需要:

  • 提供 HTTP 服务而不是使用本地文件预览;
  • 监听文件的变化并自动刷新网页,做到实时预览;
  • 支持 Source Map,以方便调试。

前面打包是把包打包到硬盘上的。在开发时,需要配置一个开发服务器,这个开发服务器可以直接让我们在内存中打包,速度是远远高于硬盘的。我们之前用的脚手架,都是在内存中打开。

前面已安装该开发服务器,叫webpack-dev-server

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

webpack-dev-server能够修改后实时更新打包

但是一旦动了配置文件,便需要重新打包

在webpack.config.js中配置开发服务器

    //配置开发服务器端口
 devServer : {
 port : 8080
} 

之前打包是使用webpack进行打包的,直接是在硬盘上的打包,现在我们需要使用内存打包。

在终端控制台输入:

npx webpack serve

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

访问之,如下:(因为此时打包的文件里无index.html)

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

4.配置开发、生产模式脚本并执行

在package.json中配置脚本,如下 :

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

执行脚本,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

5.html-webpack-plugin将打包后的js插入html页面

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

module.exports = {
  mode: "development", // 开发打包
  // 入口
  // entry: "./src/main.js",
  // entry: path.resolve(__dirname, "src/main.js"),  // 绝对路径
  entry: {
    // app表示你打包后的资源名字就是app
    app: path.resolve(__dirname, "src/main.js"),  // 绝对路径
  },
  // 出口
  output: {
    path: path.resolve(__dirname, "dist"),  // 绝对路径
    // filename:"bundle.js"  // 一捆  一束
    filename: "js/[name].[chunkhash:8].js"  // 一捆  一束
  },
  // 配置开发服务器
  devServer: {
    port: 8080
  },
 plugins : [
 new  HtmlWebpackPlugin ({
      //相对路径 相对于启动nodejs服务器的目录在这里也就是react-webpack
 template : "./public/index.html"
})
]
}

回顾一下,目前用到的依赖:

//webpack核心插件
"webpack": "^5.73.0",
//webpack命令插件
"webpack-cli": "^4.10.0",
//开发服务器插件
"webpack-dev-server": "^4.9.2",
//将打包的js插入指定html页面插件
"html-webpack-plugin": "^5.5.0",

三 配置loader处理除JS|JSON外JS高级语法|JSX|CSS|图片等

(一) 前置知识

webpack眼中一切都是模块,默认情况下,只能理解js文件和json文件,这是webpack自带的能力,其它模块,webpack默认就不能处理了。 loader 能让 webpack 能够去处理其他类型的文件(比如css类型文件,图片类型等),并将它们转换为有效模块。所以说要学习很多loader

  • less-loader 把less翻译成 css
  • css-loader 把 css 代码转换为有效模块,让webpack处理
  • sass-loader 把 sass 翻译成 css
  • babel-loader 可以转译 JavaScript 文件,加载后,让一些插件来翻译语法。 如:箭头函数==>普通函数,let==>var。只有babel-loader还不行,还需要学习很多插件。ES6+它里面的语法非常多,意味着翻译语法的插件非常多。有一个概念,叫预设,预设是插件的集合。

谷歌浏览器可以识别,但是有的浏览器是不认识的。也就是说,webapck对于ES6+中的一些语法,它也不能直接转化成ES5,不能转化成ES5,浏览器对ES5的兼容性是最好。

我们需要使用loader,loader就是把webpack不能识别的模块,转化成webpack可以识别的模块。

如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

JS模块中有高级语法,高级语法,如何转化成低级语法,让webpack识别呢?

答:最最最最最厉害的就是babel。

ES6中的语法,非常多,你要转化语法,需要安装对应插件

如你要把箭头函数转化成普通函数,那你就需要安装一个箭头函数转普通函数的插件,如你要把let转化成var,你需要安装一把let转成var的插件。也就说如果项目中用到了非常多的ES6语法,都需要转化,那就可以安装500个插件

babel给我们封装了很多预设,预设是插件集合,也就是集合中包含了很多的插件

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

如有一个预设,它可以把ES6中的大部分语法,转化成ES5,这个预设叫@babel/preset-env。

预设并不是转化所有语法,仅仅是大部分的,个别语法转化不了,需要单独安装插件。

  • 后面需要学习一堆的loader,去转化不同的模块(使用loader来处理)。

    • .js
    • .vue vue-loader
    • .jsx
    • .ts
    • .png
    • .less
    • .sass
    • .css
    • .json
    • .....
  • 也需要学习一堆的插件,插件是用来增强webpack。

(二) 打包JS 模块中的高级语法

1.相关依赖

  • babel-loader依赖:加载指定js
  • @babel/preset-env依赖:翻译指定的js--将es6+转回为es5让所有浏览器可以识别

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

2.配置

  1. 配置babel-loader加载

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

  module : {
 rules : [
 // 当webpack在工作时,遇到了以.js结束的模块,使用bable-loader进行加载
 // babel-loader是用来加载模块的,加载完成后,还需要使用@babel/xxx进行编译
 // 编译成ES5代码
            //查找以.js结束的字符串文件名?
{ test : /. js $/ , use : "babel-loader" }
]
}, 
  1. 配置@babel/preset-env预设

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

module.exports = {
 // 预设(是插件的集合)
 presets : [
[ '@babel/preset-env' ]
],
    // 插件(某个特定的语法)
    plugins: [

    ]
}

4.执行

使let变var等...

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

5.说明

上面使用的预设不能打包装饰器,需要单独去安装对应的插件(打补丁),如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

(三) 打包JSX 模块( react )

1.相关依赖

 "@babel/preset-react" :  "^7.17.12" ,
"react": "^18.2.0",
"react-dom": "^18.2.0"

2.配置

  1. 配置babel-loader加载

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

    module: {
        rules: [
// 打包时,我们不希望webpack去打包node_module配置exclude: /node_modules/
            { test : /.(js| jsx |ts|tsx)$/ , use : "babel-loader" , exclude : /node_modules/ },
        ]
    }
  1. 配置@babel/preset-react预设

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

module.exports = {
    // 预设(是插件的集合)
    presets: [
[ '@babel/preset-react' ]
    ],
    // 插件(某个特定的语法)
    plugins: [

    ]
}

(四) 打包VUE模块(vue)

1.相关依赖

  "vue-loader" :  "^17.0.0" ,
 "vue-style-loader" :  "^4.1.3" ,
 "vue-template-compiler" :  "^2.6.14" ,
 "vue-template-loader" :  "^0.4.1" ,
    "vue": "^3.2.37"

2.配置

  1. 配置vue-loader加载

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

 { test : /.vue$/ , use : "vue-loader" } 
  1. 配置VueLoaderPlugin插件

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

  const { VueLoaderPlugin } = require ( "vue-loader" )
    plugins: [
 new  VueLoaderPlugin ()
    ]

(五) 打包CSS、SASS(SCSS)、LESS模块(内部样式)

1.相关依赖

  "css-loader" :  "^6.7.1" ,
 "style-loader" :  "^3.3.1" ,
    "sass-loader" :  "^13.0.0" ,
 "less-loader" :  "^11.0.0" ,
    "sass": "^1.52.3",
    "less": "^4.1.3"

2.配置xxx-loader加载

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

            // webpack工作时,遇到css结尾文件,先用css-loader加载解析,返回css代码
            // 交给style-loader处理,后以js形式将css代码插入head标签中,也就是内部样式
            // 从后往前处理,先css-loader后style-loader use: ["style-loader", "css-loader"]
{ test : /.css$/ , use : [ "style-loader" , "css-loader" ] },
            // 先sass-loader后css-loader后style-loader
{ test : /.(sass|scss)$/ , use : [ "style-loader" , "css-loader" , "sass-loader" ] }
            { test : /.less$/ , use : [ "style-loader" , "css-loader" , "less-loader" ] } 

(六) 打包图片

1.前置知识

在webpack眼中,一切都是模块,图片当然也是模块。

在webpack4中,有两个laoder可以处理,在wabpack5中这两个laoder就淘汰了,这两个laoder如下:(url-loader比file-loader更强大)

  • url-loader
  • file-loader

在webpack5中上面的两个laoder就淘汰了,对于图片的处理,webpack内置好了

相当于是file-loader

2.相关依赖

  "file-loader" :  "^6.2.0" ,
 "url-loader" :  "^4.1.1" 

3.配置

  1. 方式一 url-loader

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

           //字符串,不过可设置limit:小于字符串,超过图片
 //{ test: /.(png|jpg|svg|gif|jepg|webp)$/, use: "url-loader" }           
            {
 test : /.(png|jpg|svg|gif|jpeg|webp)$/ ,
 use : [{
 loader : 'url-loader' ,
                    options : {
                        // limit单位是字节    1个字节 = 8位
                        //                  1KB = 1024个字节
                        //                  1MB = 1024KB
                        limit : 1024 * 50, // 如果图片小于50kb,打包字符串,如果图片大于50kb,打包成图片
                        name: 'imgs/[name].[hash:8].[ext]'
                    }
                }]
            },

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

  1. 方式二 file-loader

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

            //直接图片
{ test : /.(png|jpg|svg|gif|jepg|webp)$/ , use : "file-loader" } 

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

  1. 方式三 webpack内置图片处理

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

  // type: "asset/resource" 相当于使用了file-loader
            {
                test : /.(png|jpg|svg|gif|jpeg|webp)$/ , type : "asset/resource" , generator: {
                    filename: 'imgs/[name].[hash:8].[ext]'
                }
            },

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

四 进阶使用Webpack

(一) 将配置拆分为公共、开发、生产配置

打包分两种,一种是开发时的打包,一种是生产时的打包。

不同的打包方式有不同的配置的,两种打包方式,也就是有两种配置,但是这两种配置中有一些公共的配置。

把这些配置区分出来,创建如下的文件,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

1.公共的配置

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

2.开发配置

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

3.生产配置

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

4.导入至webpack.config.js并用webpack-merge合并

const { merge } = require ( 'webpack-merge' )
//导入三个配置
const config = require ( "./config/config" )
const dev = require ( "./config/dev" )
const pro = require ( "./config/pro" )

//合并三个配置-简化版
// 当运行npm run dev 期望dev.js和config.js生效
// 当运行npm run pro 期望pro.js和config.js生效
// { development }是执行脚本传入的env的属性
module . exports = function ( { development } ) {
 return  merge (config, development ? dev : pro)
}

// 合并三个配置-普通版
// module.exports = function (dev) {
// 在webpack.config.js中就可以得到执行脚本传入的env
// console.log(env);//{ WEBPACK_SERVE: true, development: true }
// 这里是对象解构赋值,取哪个属性值写哪个属性名即可
//     let { development } = env
//     if (development) {
//         return merge(config, dev)
//     } else {
//         return merge(config, pro)
//     }
// }

5.在package.json中配置脚本并执行

  "scripts": {
  ...
    "dev": "webpack serve --env development --config webpack.config.js",
    "pro": "webpack --env production --config webpack.config.js"
    }
//生产模式
npm run pro
//开发模式
npm run dev

(二) html-webpack-plugin将js引入指定html

1.配置

        // 将js引入指定html插件
        new HtmlWebpackPlugin({
            template: './public/index.html',//相对路径 相对于启动nodejs服务器的目录在这里也就是react-webpack
            // template: path.resolve(__dirname, "../", 'public/index.html')//绝对路径
            inject:"body",//把js脚本注入到body结束标签之前
            filename: "index1.html",// 指定打包成功后页面的名字
            title: "htmlwebpackplugin",//用来指定页面的title标题
            favicon: path.resolve(__dirname, "../", "favicon.ico")//配置icon
        }),

2.注意

  • title: "htmlwebpackplugin"

还需要在页面中title标签位置写如下代码

 <%= htmlWebpackPlugin.options.title %> 
  • inject:"body"

不设inject的话, 默认把打包后js插入到了head结束标签之前

2.执行

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

(三) postcss-loader处理css兼容

postcss是JavaScript转换样式的工具,这个工具能处理css兼容问题。

就是这个工具能给我们写的css代码添加一些兼容的前缀

1.相关依赖

 "autoprefixer" :  "^10.4.7" ,
"postcss" :  "^8.4.14" ,
"postcss-loader" :  "^7.0.0" ,
"postcss-preset-env" :  "^7.7.1" 

2.配置

  1. 在项目根目录下创建 postcss.config.js 文件

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

module.exports = {
    plugins: {
        "autoprefixer": {
            "overrideBrowserslist": [
                // 兼容IE7以上浏览器
                "ie >= 8",
                // 兼容火狐版本号大于3.5浏览器
                "Firefox >= 3.5",
                // 兼容谷歌版本号大于35浏览器,
                "chrome >= 35"
            ]
        }
    }
}
  1. 修改webpack配置

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

            { test: /.css$/, use: ["style-loader", "css-loader", "postcss-loader"] },
            { test: /.(sass|scss)$/, use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"] },

3.执行

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

(四) 配置代理解决跨域(前端处理)

在做网络请求的时候,前端最常见的问题就是跨域,分别可以在前端和后端处理

  • 前端处理

    • JSONP(需要服务器端支持)
    • proxy代理(开发模式)
  • 后端处理

    • cors

1.出现跨域问题

  1. 后端

    1. 创建服务器:

    2. 【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

    3. const express = require("express")
      const path = require("path")// 创建 express 实例const app = express();
      app.get("/malu",(req,res)=>{
          res.send({code:1,data:"你好,我是服务器~"})})
      app.listen(3000,()=>{
          console.log('服务器启动了,端口是3000');})
      
    4. 依赖:

      • 【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种
    5. 测试服务器:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

  1. 前端

    1. 写axios代码,向服务器发请求
    2. 【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种
    3. 产生了跨域问题

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

2.webpack配置代理解决跨域

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

    devServer: {
        port: 8080,
        client: {
            // 只弹出报错
            overlay: {
                errors: true,
                warnings: false
            }
        },
        // 代理
 proxy : {
 '/api' : { //定义一个标记,如以后api开头的请求都走代理的设置
 target : 'http://localhost:3000/' , // 目标域名
 // 发送请求头中host会设置成target
 changeOrigin : true , // 改变源到目标域名,允许设置请求头
 pathRewrite : { '^/api' : '' } // 重写路径,去除/api部分
    }
    }
        }

(五) ProvidePlugin把某些包放到全局(webpack内置)

1.分析需要原因

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

如何把某些包放到全局中,此时需要使用ProvidePlugin

2.配置

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

const { ProvidePlugin } = require("webpack")
    plugins: [
        // 配置ProvidePlugin将某些包如React放到全局中
 new  ProvidePlugin ({
 React : path. resolve (__dirname, "../" , "node_modules/react/index.js" )
})
    ]

(六) source-map在Debug时显示原始代码位置信息(而非压缩后)

1.分析需要原因

我们可以通过 devtool 来设置增强调试过程,通过设置 devtool 生成source map。

  • source map 是一个信息文件,里面存储着代码压缩前后的位置信息。
  • 即可以在Debug时直接显示原始代码的位置信息,而不是压缩后的,极大方便后期调试

开发环境下默认生成的Source Map ,记录的是生成后的代码的位置。会导致运行时报错的行数与源代码的行数不一致的问题。

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

看一下控制台,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

解决方案:在webpack.dev.config.js中添加如下配置,即可保证运行时报错的行数与源代码的行数保持一致。

2.配置

Source Map 的最佳实践

  • 开发模式下,建议直接把devtool 的值设置为 source-map ,可以直接定位到具体的错误行
  • 生产环境下,建议关闭Source Map 或者 将devtool 设置为 hidden-nosources-source-map ,防止源码泄漏,提高网站的安全性

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

    // 使报错行对应的是源代码而非打包后代码
    devtool: "source-map"

此时报错的位置和控制台中就保持一样的了,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

在生产中,可以不去配置source-map,上线的也是打包后的代码

可以不配置,也可以配置 :

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

或者不配置:

module.exports = {mode:"development",// devtool:"hidden-nosources-source-map"}

(七) 把第三方包抽离出来

1.分析需要原因

现在尝试去打包,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

分析之,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

可以看一下,之前打包vue,生成的js文件,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

2.配置

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

  entry : {
        // 把react和react-dom分离出去,形成一个chunk
        // 方便后面cdn优化
 chunk : [ 'react' , 'react-dom/client' ],
        //app可随便修改,为main.js打包后的文件名
        app: {
            import: path.resolve(__dirname, "../", "src/main.js"),
 // 写的业务代码是依赖第三方包的
 dependOn : "chunk"
        }
    },

3.执行

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

(七点五) 抽离css(外部样式)

在生产打包时,需要把css抽离出来

此时我们需要用到一个插件,这个插件中带了一个loader

1.依赖

  "mini-css-extract-plugin" :  "^2.6.1" , 

2.配置

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

const MiniCssExtractPlugin = require("mini-css-extract-plugin")
    plugins: [
 // 分离css出来单独打包
 new  MiniCssExtractPlugin ({
 filename : 'css/[name].[contenthash:8].css'
})
    ]

3.执行

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

(八) 压缩CSS

1.分析需要原因

打包CSS,书写CSS代码如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

在main.js中引入css,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

打包:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

2.依赖

 "optimize-css-assets-webpack-plugin" :  "^6.0.1" 

3.配置

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

// 压缩打包后的css
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin")
 plugins : [
        // 分离css出来单独打包
        new MiniCssExtractPlugin({
            filename: 'css/[name].[contenthash:8].css'
        }),
 // 压缩打包后的css--即变成一行
 new  OptimizeCssAssetsWebpackPlugin ()
    ]

(九) ESLint

1.前提知识

为了统一规范团队代码习惯,降低代码出错风险,eslint已经成为前端项目必备法器。简单来说,写代码必须遵循一定的规范,至于是什么规范,我们可以自己定义。

eslint是用来进行代码检测。也非常重要,在很多公司,都是要求使用eslint的,如果代码写的不符合要求,有可能代码就提交到不到仓库。在很早之前,有一个laoder,叫eslint-loader来校验代码,现在这个laoder已经淘汰了。现在使用的是一个插件,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

2.依赖

  "eslint" : "^8.18.0" ,
 "eslint-webpack-plugin" : "^3.1.1" 
  • eslint里面包含了很多的校验规则

  • eslint-webpack-plugin使用eslint来查找和修复js代码中的问题

    • eslint-webpack-plugin这个插件不能进行校验,这个插件是把eslint集成到webpack中的。
  • 代码校验是在开发时进行校验的,配置就需要配置到开发环境中

3.配置

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

const  ESLintPlugin = require ( "eslint-webpack-plugin" )

module.exports = {
    mode:"development",
    devServer:{
        port:8080
    },
    plugins:[
 new  ESLintPlugin ({
 eslintPath : 'eslint' ,
 extensions :[ 'js' , 'jsx' , 'ts' , 'tsx' , 'vue' ],
 exclude :[ 'node_modules' ]
})
    ]
}

此时打包后报错

上面的插件仅仅是把eslint集成到webpack中,对于eslint的配置文件,还需要单独配置

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

创建eslint的配置文件,有多种方式

创建一个eslint的配置文件, 如下

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

module . exports = {
 env : {
 node : true ,
 browser : true ,
 es6 : true ,
},
 // 支持ES6并不代表支持所有ES6新语法, 设置为"module" 支持 ECMAScript 模块
 // 解析配置
 parserOptions : {
 sourceType : 'module' ,
 ecmaFeatures : {
 'jsx' : true
}
},
 // 个人难以制定大而全的规范
 // 可以借用大公司已成熟方案,再根据项目情况稍加修改
 // 这里我们引用Airbnb
 extends : "airbnb-base" ,
    // 配置自定义的规则
 rules : {
 // JS文件中不支持console.log()
 // 'no-console': 'warn',
 // "semi": "error",
},
}; 
  • eslint中还有哪些规则呢?

如下:www.cnblogs.com/zhenfeng25/…

"no-alert": 0,//禁止使用alert confirm prompt
"no-array-constructor": 2,//禁止使用数组构造器
"no-bitwise": 0,//禁止使用按位运算符
"no-caller": 1,//禁止使用arguments.caller或arguments.callee
......
  • 如果不想让eslint检测我们的src下面所有的代码

可以创建一个.eslintignore的配置文件,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

4.执行

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

(十) 使用vue脚手架中的eslint

创建vue脚手架创建项目,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

弹出vue脚手架中webpack的配置,如下:

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

五 "鸡肋"系列

(一) 配置路径别名

1.配置

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

  // 配置路径相关
 resolve : {
 // 别名
 alias : {
 "@" : path. resolve (__dirname, "../" , "src" )
},
 // 扩展、延长
 extensions : [ '.js' , '.jsx' , '.ts' , '.tsx' , '.vue' ]
} 

2.使用

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

(二) browserslistrc表示当前项目的浏览器兼容情况

browserslistrc文件是为了表示当前项目的浏览器兼容情况,使用方式有三种:

  • 在package.json中设置
  • 设置成独立的配置文件
  • 某些插件需要重新设置browserslist

我们参考Vue项目的环境配置,选择第二种方式,设置成独立的配置文件

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

1%   // 兼容市场上占有率超过1%的浏览器(世界级)
last 2 versions  // 兼容浏览器最近的两个版本
not dead // 不支持24个月内没有官方支持或者更新的浏览器
not ie 11  // 不支持ie 11

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

(三) 配置ProgressPlugin插件(webpack内置)

1.配置

const { ProgressPlugin } = require ( "webpack" ) 

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

2.执行

【菜狗学前端】超超超详尽Webpack实践笔记超超超详尽的webpack使用,实践笔记!!!知原因晓使用,一撸到底!各种

转载自:https://juejin.cn/post/7360879591236124706
评论
请登录