• Webpack


    目录

    一、webpack 的基本配置

    1、 webpack 的默认配置

    2、在命令行中修改打包的默认入口文件名、默认出口文件名和默认出口文件

    3、在webpack.config.js 配置文件中修改webpack 的配置

    4、修改了webpack.config.js 的文件名称后,如何运行配置文件?


    一、webpack 的基本配置

    1、 webpack 的默认配置

    • 默认入口文件  src/index.js
    • 默认出口文件 dist/main.js
    • 默认出口文件夹 dist
    • 可以在命令行中通过 npx webpack 进行打包

    2、在命令行中修改打包的默认入口文件名、默认出口文件名和默认出口文件

    • --entry 修改文件的默认入口文件名
    • --output-filename 修改文件的默认出口文件名
    • --output-path 修改文件的默认出口文件夹
    npx webpack --entry ./src/main.js --output-filename bundle.js --output-path ./build
    

    3、在webpack.config.js 配置文件中修改webpack 的配置

    1. const path = require("path")
    2. // 因为webpack 是运行在node中,所以要使用node 的commonJS 模块化语法
    3. module.exports = {
    4. entry: "./src/main.js",
    5. output: {
    6. filename: "bundle.js",
    7. // __dirname 获取当前文件所在路径
    8. // path 的值需要使用绝对路径
    9. path: path.resolve(__dirname, "./build")
    10. }
    11. }

    4、修改了webpack.config.js 的文件名称后,如何运行配置文件?

    • 如果将webpack.config.js 修改为wp.config.js 后在命令行中输入npx webpack 是找不到默认的配置文件的
    • 可以再命令行中输入npx webpack --config wp.config.js 运行改名后的webpack配置文件 或者在package.json 文件中写脚本
    1. // 默认的打包方式 webpack.config.js
    2. "scripts": {
    3. "build": "webpack"
    4. }
    5. // 然后在命令行中运行脚本
    6. npm run build
    1. // 修改配置文件名后的打包方式
    2. "scripts": {
    3. "build": "webpack --config wb.config.js"
    4. }
    5. // 然后在命令行中运行脚本
    6. npm run build

    二、loader

    1、对于css 文件的处理

    1. npm install css-loader -D
    2. // css-loader 只负责解析css 文件,不会将文件插入到页面中
    3. // 所以这时需要用到style-loader
    4. npm install style-loader -D
    5. const path = require("path")
    6. module.exports = {
    7. entry: "./src/main.js",
    8. output: {
    9. filename: "bundle.js",
    10. path: path.resolve(__dirname, "./build")
    11. }
    12. module: {
    13. rules: [
    14. {
    15. // 告诉webpack 匹配什么类型的文件, 通常会设置成正则表达式
    16. test: /\.css$/,
    17. // 告诉webpack 使用什么样的loader 来处理匹配到的文件
    18. // use 中多个loader 的使用顺序是从后往前的
    19. use: [
    20. { loader: "style-loader", "css-loader" }
    21. // { loader: "style-loader" },
    22. // { loader: "css-loader" }
    23. ]
    24. }
    25. ]
    26. }
    27. }

    2、对于less 文件的处理

    1. npm install less-loader -D
    2. const path = require("path")
    3. module.exports = {
    4. entry: "./src/main.js",
    5. output: {
    6. filename: "bundle.js",
    7. path: path.resolve(__dirname, "./build")
    8. }
    9. module: {
    10. rules: [
    11. {
    12. test: /\.css$/,
    13. use: [
    14. { loader: "style-loader", "css-loader" }
    15. ]
    16. },
    17. {
    18. test: /\.less$/,
    19. use: [
    20. { loader: "style-loader", "less-loader", "less-loader"}
    21. ]
    22. }
    23. ]
    24. }
    25. }

    3、PostCSS 中的插件

    1、autoprefixer 自动为有兼容性问题的css 样式添加前缀

    当使用user-selece: none; (用户是否能选中)这样的具有兼容性问题的css 样式时,需要在该样式前加浏览器前缀,PostCSS 可以自动检测该css 样式是否具有兼容性问题,并自动添加浏览器前缀

    1. npm install postcss-loader -D
    2. // 自动添加浏览器前缀的插件
    3. npm install autoprefixer -D
    4. const path = require("path")
    5. module.exports = {
    6. entry: "./src/main.js",
    7. output: {
    8. filename: "bundle.js",
    9. path: path.resolve(__dirname, "./build")
    10. }
    11. module: {
    12. rules: [
    13. {
    14. test: /\.css$/,
    15. use: [
    16. "style-loader",
    17. "css-loader",
    18. {
    19. loader: "postcss-loader",
    20. options: {
    21. postcssOptions: {
    22. plugins: [ "autoprefixer" ]
    23. }
    24. }
    25. }
    26. ]
    27. },
    28. {
    29. test: /\.less$/,
    30. use: [
    31. "style-loader",
    32. "css-loader",
    33. "less-loader",
    34. "postcss-loader"
    35. ]
    36. }
    37. ]
    38. }
    39. }

    或通过postcss.config.js 文件来配置postcss-loader

    1. npm install postcss-loader -D
    2. // 自动添加浏览器前缀的插件
    3. npm install autoprefixer -D
    4. // webpack.config.js
    5. const path = require("path")
    6. module.exports = {
    7. entry: "./src/main.js",
    8. output: {
    9. filename: "bundle.js",
    10. path: path.resolve(__dirname, "./build")
    11. }
    12. module: {
    13. rules: [
    14. {
    15. test: /\.css$/,
    16. use: [
    17. "style-loader",
    18. "css-loader",
    19. "postcss-loader"
    20. ]
    21. },
    22. {
    23. test: /\.less$/,
    24. use: [
    25. "style-loader",
    26. "css-loader",
    27. "less-loader",
    28. "postcss-loader"
    29. ]
    30. }
    31. ]
    32. }
    33. }
    34. // postcss.config.js
    35. module.exports = {
    36. plugins: [
    37. "autoprefixer"
    38. ]
    39. }

     2、postcss-preset-env 为开发时的主要功能预设配置(功能更强大,包括css 的浏览器兼容性问题)

    1. npm install postcss-loader -D
    2. npm install postcss-preset-env -D
    3. // webpack.config.js
    4. const path = require("path")
    5. module.exports = {
    6. entry: "./src/main.js",
    7. output: {
    8. filename: "bundle.js",
    9. path: path.resolve(__dirname, "./build")
    10. }
    11. module: {
    12. rules: [
    13. {
    14. test: /\.css$/,
    15. use: [
    16. "style-loader",
    17. "css-loader",
    18. "postcss-loader"
    19. ]
    20. },
    21. {
    22. test: /\.less$/,
    23. use: [
    24. "style-loader",
    25. "css-loader",
    26. "less-loader",
    27. "postcss-loader"
    28. ]
    29. }
    30. ]
    31. }
    32. }
    33. // postcss.config.js
    34. module.exports = {
    35. plugins: [
    36. "postcss-preset-env"
    37. ]
    38. }

    4、webpack 处理图片

    1、asset module type 资源模块类型

    • 在webpack5 之前加载资源需要用到一些loader,比如:raw-loader、url-loader、file-loader
    • 在webpack5 开始,可以直接通过资源模块类型,来替代上面的loader

    资源模块类型,通过添加4种新的模块类型,来替换loader

    • asset/resource 发送一个单独的文件并导出URL,之前通过file-loader 实现(打包图片并且该图片有自己的地址,将地址设置到img/bgi 中的url 中。缺点:多了对图片加载的网络请求,几张图片就请求几次)
    • asset/inline 导出一个资源的data URI,之前通过url-loader 实现(将图片进行base64 的编码,并且直接将编码后的源码放到对应打包的js 文件中。缺点:造成打包后的js 文件比较大,造成对js 文件的下载和解析时间比较长)  (合理的图片加载规范:对于小图片可以进行base64 编码,对于大图片,可以进行单独的图片打包,形成url 地址,单独的请求这个url 的图片。)
    • asset/source 导出资源的源代码,之前通过使用raw-loader 实现(不常用)
    • asset 在导出一个data URI 和发送一个单独的文件之间自动选择,之前通过url-loader,并且配置资源体积限制实现;
    1. const path = require("path")
    2. module.exports = {
    3. entry: "./src/main.js",
    4. output: {
    5. filename: "bundle.js",
    6. path: path.resolve(__dirname, "./build")
    7. }
    8. module: {
    9. rules: [
    10. {
    11. test: /\.css$/,
    12. use: [ "style-loader", "css-loader", "postcss-loader" ]
    13. },
    14. {
    15. test: /\.less$/,
    16. use: [ "style-loader", "css-loader", "less-loader", "postcss-loader" ]
    17. },
    18. {
    19. test: /\.(png|jpe?g|svg|gif)$/,
    20. // 资源模块类型
    21. type: "asset"
    22. }
    23. ]
    24. }
    25. }

    2、对打包的图片重命名、根据图片大小区分打包方式

    1. const path = require("path")
    2. module.exports = {
    3. entry: "./src/main.js",
    4. output: {
    5. filename: "bundle.js",
    6. path: path.resolve(__dirname, "./build")
    7. }
    8. module: {
    9. rules: [
    10. {
    11. test: /\.(png|jpe?g|svg|gif)$/,
    12. // 资源模块类型
    13. type: "asset",
    14. // 为不用大小的图片区分打包的方式
    15. parser: {
    16. dataUrlCondition: {
    17. // 小于60kb 就使用base64, 大于64kb 就单独进行打包
    18. maxSize: 60 * 1024
    19. }
    20. }
    21. // 对打包后的图片重新命名
    22. generator: {
    23. // img/: 表示将图片资源单独放到img 文件夹
    24. // name: 用于指向原来的图片名称
    25. // hash: webpack 生成的唯一的hash 值(:8 截取前8位)
    26. // ext: 用于指向原来的图片后缀名
    27. filename: "img/[name]_[hash:8][ext]"
    28. }
    29. }
    30. ]
    31. }
    32. }

    5、webpack 对vue 文件的处理

    1. npm install vue-loader -D
    2. const path = require("path")
    3. const { VueLoaderPlugin } from = require('vue-loader/dist/index')
    4. module.exports = {
    5. entry: "./src/main.js",
    6. output: {
    7. filename: "bundle.js",
    8. path: path.resolve(__dirname, "./build")
    9. }
    10. module: {
    11. rules: [
    12. {
    13. test: /\.css$/,
    14. use: [ "style-loader", "css-loader", "postcss-loader" ]
    15. },
    16. {
    17. test: /\.less$/,
    18. use: [ "style-loader", "css-loader", "less-loader", "postcss-loader" ]
    19. },
    20. {
    21. test: /\.(png|jpe?g|svg|gif)$/,
    22. // 资源模块类型
    23. type: "asset"
    24. },
    25. {
    26. test: /\.vue$/,
    27. use: [ "vue-loader" ]
    28. }
    29. ]
    30. },
    31. plugins: [
    32. new VueLoaderPlugin()
    33. ]
    34. }

     6、webpack 解析文件或文件夹

    • 如果是文件,当省略文件后缀名时,通过webpack 配置默认添加文件后缀名。当引用App.vue 文件时,省略.vue 文件后缀名,如:import App from '@/views/App',可以通过webpack 的resolve.extensions 进行配置后默认添加文件后缀名
    • 如果是文件夹,webpack 会根据resolve.mainFiles 查找index 文件,再通过resolve.extensions 来解析扩展名
    1. const path = require("path")
    2. module.exports = {
    3. entry: "./src/main.js",
    4. output: {
    5. filename: "bundle.js",
    6. path: path.resolve(__dirname, "./build")
    7. }
    8. module: {
    9. rules: [
    10. {
    11. test: /\.css$/,
    12. use: [ "style-loader", "css-loader", "postcss-loader" ]
    13. },
    14. {
    15. test: /\.less$/,
    16. use: [ "style-loader", "css-loader", "less-loader", "postcss-loader" ]
    17. },
    18. {
    19. test: /\.(png|jpe?g|svg|gif)$/,
    20. // 资源模块类型
    21. type: "asset"
    22. },
    23. {
    24. test: /\.vue$/,
    25. use: [ "vue-loader" ]
    26. }
    27. ]
    28. },
    29. resolve: {
    30. extensions: [".js", ".json", ".vue", ".jsx", ".ts", ".tsx"],
    31. // 为固定的目录配置重命名
    32. alias: {
    33. src: path.resolve(__dirname, "./src")
    34. }
    35. }
    36. plugins: [
    37. new VueLoaderPlugin()
    38. ]
    39. }

    三、babel

    当遇到ES6+ 、ts、jsx 的代码时通过babel 进行处理转成es5 的代码

    babel 和postcss 一样可以单独拿出来配置,放到babel.config.js 配置文件中

    babel 的预设:@babel/preset-env

    1. npm install babel-loader -D
    2. // babel 的预设
    3. npm install @babel/preset-env -D
    4. // webpack.config.js
    5. const path = require("path")
    6. module.exports = {
    7. entry: "./src/main.js",
    8. output: {
    9. filename: "bundle.js",
    10. path: path.resolve(__dirname, "./build")
    11. }
    12. module: {
    13. rules: [
    14. {
    15. test: /\.js$/,
    16. use: {
    17. loader: "babel-loader",
    18. // options: {
    19. // presets: [
    20. // "@babel/preset-env"
    21. // ]
    22. }
    23. }
    24. }
    25. ]
    26. }
    27. }
    28. // babel.config.js
    29. module.exports = {
    30. presets: [
    31. "@babel/preset-env"
    32. ]
    33. }

    四、plugin

    1、loader 和plugin 的区别:

    1. loader 是用于特定的模块类型进行转换;
    2. plugin 可以用于执行更加广泛的任务,比如打包优化、资源管理、环境变量注入等;

    2、CleanWebpackPlugin

    当重新打包时,都需要手动删除dist 文件夹,可以通过clean-webpack-plugin 在打包时自动删除dist 文件夹

    1. npm install clean-webpack-plugin -D
    2. const path = require("path");
    3. const { CleanWebpackPlugin } = require("clean-webpack=plugin");
    4. module.exports = {
    5. entry: "./src/main.js",
    6. output: {
    7. filename: "bundle.js",
    8. path: path.resolve(__dirname, "./build")
    9. }
    10. plugins: [
    11. new CleanWebpackPlugin()
    12. ]
    13. }

    3、HtmlWebpackPlugin

    当进行打包时,不会打包index.html 文件,可以通过html-webpack-plugin 在打包时自动生成index.html 文件,并进行打包

    1. npm install clean-webpack-plugin -D
    2. npm install html-webpack-plugin -D
    3. const path = require("path");
    4. const { CleanWebpackPlugin } = require("clean-webpack=plugin");
    5. const HtmlWebpackPlugin = require("html-webpack-plugin");
    6. module.exports = {
    7. entry: "./src/main.js",
    8. output: {
    9. filename: "bundle.js",
    10. path: path.resolve(__dirname, "./build")
    11. }
    12. plugins: [
    13. new CleanWebpackPlugin(),
    14. new HtmlWebpackPlugin({
    15. title: '网页标题',
    16. // 当不想使用默认生成的index.html 模板时,可以自己设置要使用的index.html 文件
    17. template: './index.html'
    18. })
    19. ]
    20. }

    4、DefinePlugin (注入变量)

    1. npm install clean-webpack-plugin -D
    2. npm install html-webpack-plugin -D
    3. const path = require("path");
    4. const { CleanWebpackPlugin } = require("clean-webpack=plugin");
    5. const HtmlWebpackPlugin = require("html-webpack-plugin");
    6. const { DefinePlugin } = require("webpack");
    7. module.exports = {
    8. mode: "development",
    9. entry: "./src/main.js",
    10. output: {
    11. filename: "bundle.js",
    12. path: path.resolve(__dirname, "./build")
    13. }
    14. plugins: [
    15. new CleanWebpackPlugin(),
    16. new HtmlWebpackPlugin({
    17. title: '网页标题',
    18. // 当不想使用默认生成的index.html 模板时,可以自己设置要使用的index.html 文件
    19. template: './index.html'
    20. }),
    21. new DefinePlugin({
    22. BASE_URL: "'./'",
    23. coderwhy: "'why'",
    24. counter: "123"
    25. })
    26. ]
    27. }
    28. // 定义的是全局变量,可以在任何地方直接使用
    29. // main.js
    30. console.log(BASE_URL);
    31. console.log(process.env.NODE_ENV);

    五、Mode 模式

    • 默认值是production
    • 可选值有:"none" | "development" | "production"
    • 当设置为"development",是会在DefinePlugin 中的process.env.NODE_ENV 设置为"development",并为模块和chunk 启用有效的名
    • 当设置为 "production" 时,是会在DefinePlugin 中的process.env.NODE_ENV 设置为"production",并为模块和chunk 启用确定性的混淆名

    六、webpack 搭建本地服务器(自动打包,自动刷新浏览器)

     1、webpack-dev-server

    开启一个本地服务器,供开发时使用

    1. npm install webpack-dev-server -D
    2. // package.json
    3. "scripts": {
    4. "serve": "webpack serve --config webpack.config.js"
    5. }
    6. npm run serve

    2、devServer 配置

    1. const path = require("path");
    2. module.exports = {
    3. mode: "development",
    4. entry: "./src/main.js",
    5. output: {
    6. filename: "bundle.js",
    7. path: path.resolve(__dirname, "./build");
    8. }
    9. devServer: {
    10. // 默认为true
    11. hot: true,
    12. // 默认为localhost(127.0.0.1),也可以修改为0.0.0
    13. host: "0.0.0",
    14. // 默认是8080
    15. port: 8888,
    16. // 运行代码后自动打开浏览器
    17. open: true
    18. // 是否对文件进行压缩
    19. compress: true
    20. }
    21. }

    3、认识模块热替换(HMR)

    • HMR 的全程是Hot Module Replacement, 翻译为模块热替换;
    • 模块热替换是指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个页面;
    • 当某一个模块发生变化,只需要加载该模块的变化,不需要刷新整个浏览器
    1. // main.js
    2. if(module.hot) {
    3. module.hot.accept("./utils.js", () => {
    4. console.log("utils更新了")
    5. })
    6. }

    七、proxy

    1、proxy 代理的配置

    proxy 是用来设置代理来解决跨域访问的问题:

    • 比如我们的一个api 请求的是http://localhost:8888,但是本地启动服务器的域名是http://localhost"8000, 这个时候发送网络请求会出现跨域的问题
    • 那么我们可以将请求先发送到一个代理服务器,代理服务器和API服务器没有跨域问题,就可以解决跨域问题了

    我们可以进行如下的设置:

    • target:表示的是代理到的目标地址,比如/api-hy/moment会被代理到http://localhost:8888/api-hy/moment;
    • pathRewrite:默认情况下,我们的/api-hy 也会被写入到URL 中,如果希望删除,可以使用pathRewrite
    • secure:默认情况下不接收转发到https的服务器上,如果希望支持,可以设置为false;
    • changeOrigin:表示是否更新代理后请求的headers 中的host 地址

    2、changeOrigin 的解析

    changeOrigin 是要修改代理请求中的headers 中的host 属性

    • 因为我们真是的请求,其实是需要通过http://localhost:8888来请求的
    • 但是因为使用了代码,默认情况下它的值是http://localhost:8000
    • 如果我们需要修改,那么可以将changeOrigin 设置为true 即可

    3、historyApiFallback

    • historyApiFallback 是开发中一个非常常见的属性,它主要的作用是解决SPA 页面在路由跳转之后,进行页面刷新时,返回404 的错误
    • boolean 值:默认是false,如果设置为true,那么在刷新时,返回404错误时,会自动返回index.html 的内容
    • object 类型的值,可以配置rewrites 属性:可以配置from 来匹配路径,决定要跳转到哪一个页面
    • 事实上devServer 中实现historyApiFallback 功能是通过connect-history-api-fallback 库的;

    八、webpack 区分环境

    1. npm install webpack-merge -D
    2. "scripts": {
    3. "serve": "webpack serve --config ./webpack.dev.config.js",
    4. "build": "webpack --config ./webpack.prod.config.js"
    5. }
    6. npm run serve
    7. npm run build
    8. // webpack.dev.config.js
    9. const { merge } = require("webpack-merge");
    10. const commonConfig = require("./webpack.comn.config.js");
    11. module.exports = merge(commonConfig, {
    12. mode: "development",
    13. entry: "",
    14. output: ""
    15. })
    16. // webpack.prod.config.js
    17. const { merge } = require("webpack-merge");
    18. const commonConfig = require("./webpack.comn.config.js");
    19. module.exports = merge(commonConfig, {
    20. mode: "production",
    21. entry: "",
    22. output: ""
    23. })
    24. // webpack.comn.config.js
    25. // 用于书写公共配置

  • 相关阅读:
    Android使用Coordinatorlayout以及自定义Behavior实现滑动折叠效果
    系统学习Python——类(class)代码的编写基础与实例:类通过继承进行定制
    11个Python循环技巧
    python文件操作
    卷积神经网络loss不下降,神经网络loss多少算正常
    说说XXLJob分片任务实现原理?
    CMake继续学习
    go~在阿里mse上使用redis.call
    那些年,我们一起追过的Python BUG
    一个工地狗变成程序猿的故事
  • 原文地址:https://blog.csdn.net/qq_50829019/article/details/134480640