一、webpack 是什么?

webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler)。在 webpack 看来, 前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理。它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)。

1.1webpack原理

webpack只是一个打包模块的机制,只是把依赖的模块转化成可以代表这些包的静态文件。webpack就是识别你的 入口文件。识别你的模块依赖,来打包你的代码。至于你的代码使用的是commonjs还是amd或者es6的import。webpack都会对其进行分析。来获取代码的依赖。webpack做的就是分析代码。转换代码,编译代码,输出代码。webpack本身是一个node的模块,所以webpack.config.js是以commonjs形式书写的(node中的模块化是commonjs规范的)

1.2webpack 五个核心概念

  1. Entry入口(Entry)指示 webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。
  2. Output输出(Output)指示 webpack 打包后的资源 bundles(bundle叫做打包后输出的文件叫做bundle) 输出到哪里去,以及如何命名
  3. LoaderLoader 让 webpack 能 够 去 处 理 那 些 非 JavaScript 文 件 (webpack 自 身 只理 解JavaScript)
  4. Plugins插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等

环境区分
ps 注意点:es6语法在页面无法识别,chunk叫做代码块, 在哪个js代码块bundle叫做打包后输出的文件叫做bundle.

二、webpack的相关配置

webpack

第一、配置css

  1. css样式文件webpack.config.js 在实际项目文件为(webpack.base.config.js)
  2. 知识点 :配置css和less时webpack本身无法处理css,需要webpack的配置,根据以下代码进行配置
  3. 命令有
    1 npm i style-loader -D
    2 npm i css-loader
    3 npm i less-loader和less
//6 resolve用来拼接绝对路径的方法
const { resolve } = require('path');
module.exports = {
  // 1webpack配置
  // 入口起点
  entry: './src/index.js', //2(webpack入口文件引入过来)
  // 3经过webpack打包后输出到
  output: {
    // 输出文件名
    filename: 'built.js', //4filename:后面的路径为webpack打包后输入文件路径
    // 5输出路径
    // 8__dirname nodejs的变量,代表当前文件的目录绝对路径
    path: resolve(__dirname, 'build') //9在实际项目当中看到build这个文件夹4
   //里面的filename: 'built.js',
    //7这里path 使用了 const { resolve } = require('path');
  },
  // 1loader的配置
  module: {
    rules: [
      //2 详细loader配置
      // 3不同文件必须配置不同loader处理
      {
        // 4匹配哪些文件 发现以css文件结尾的就会去处理
        test: /\.css$/,
        // 5使用哪些loader进行处理
        use: [
          // use数组中loader执行顺序:从右到左,从下到上 依次执行
          // 7创建style标签,将js中的样式资源插入进行,添加到head中生效
          'style-loader',
          // 6(从下到所以这里是第六步)将css文件变成commonjs模块加载js中,
          //里面内容是样式字符串
          'css-loader'
        ]
      },
      {
        test: /\.less$/,//8配置less资源和匹配哪些文件发现以less文件结尾的就会去处理
        use: [
          'style-loader',//11.3找到js代码的中css代码创建style标签放到页面
          'css-loader',//11.2说明css-loaderr负责把css负责吧css内容整合到js中
          // 9将less文件编译成css文件
          // 10需要下载 less-loader和less
          'less-loader' //11.1说明less-loader负责把less编译css
        ]
      }
    ]
  },
  // plugins的配置
  plugins: [
    // 详细plugins的配置
  ],
  // 模式
  mode: 'development', // 开发模式 或者生产环境一般使用开发模式
  // mode: 'production' //生产环境
}

第二配置html ---- plugin

  1. 下载安装 plugin 包 npm install --save-dev html-webpack-plugin
  2. 修改配置文件 插件const HtmlWebpackPlugin = require(‘html-webpack-plugin’); 必须引入
/*
  loader: 1. 下载   2. 使用(配置loader)
  plugins: 1. 下载  2. 引入  3. 使用
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); //1下载后引入

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      // loader的配置
    ]
  },
  plugins: [
    // plugins的配置
    // html-webpack-plugin
    // 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
    // 需求:需要有结构的HTML文件
    new HtmlWebpackPlugin({
      // 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

第三:打包图片资源 ----loader

1下载安装 loader 包 npm install --save-dev html-loader url-loader file-loader
const HtmlWebpackPlugin = require(‘html-webpack-plugin’); 引入
2. 修改配置文件 插件const HtmlWebpackPlugin = require(‘html-webpack-plugin’); 必须引入

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');//2引入 插件

module.exports = {
  entry: './src/index.js', //固定写法
  output: { 
    filename: 'built.js', 
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.less$/,
        // 1 要使用多个loader处理用use 
        //1.1less-loader负责把less编译css
        //1.2css-loaderr负责把css负责吧css内容整合到js中
        //1.3找到js代码的中css代码创建style标签放到页面
        use: ['style-loader', 'css-loader', 'less-loader']
      },
      {
        // 问题:默认处理不了html中img图片
        //3 处理图片资源
        test: /\.(jpg|png|gif)$/,
        //7 使用一个loader
        //8 下载 url-loader file-loader 在最外层文件夹处下载
        loader: 'url-loader',
        options: { //options这里面是loader的一个配置
          // 4图片大小小于8kb,就会被base64处理
          // 5优点: 减少请求数量(减轻服务器压力)
          // 6缺点:图片体积会更大(文件请求速度更慢)
          limit: 8 * 1024, //经过base64的处理
          // 9问题:因为url-loader默认使用es6模块化解析,
          //10而html-loader引入图片是commonjs
          // 11解析时会出问题:[object Module]
          // 12解决:关闭url-loader的es6模块化,使用commonjs解析
          esModule: false,
          // 13给图片进行重命名
          // 14[hash:10]取图片的hash的前10位 哈希值太多
          // 15[ext]取文件原来扩展名
          name: '[hash:10].[ext]'
        }
      },
      {
        test: /\.html$/,
        // 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
        loader: 'html-loader'
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({ //3 使用插件
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

第四:打包其他资源

(比如字体图标)exclude的排除意思

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      // 打包其他资源(除了html/js/css资源以外的资源)
      {
        // 排除css/js/html资源
        exclude: /\.(css|js|html|less)$/,
        loader: 'file-loader',
        options: {
          name: '[hash:10].[ext]' //hash相当于id
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

第五: devserve

作用:开发服务器自动编译自动打开浏览器和刷新服务器
特点:只会在内存中编译打包,不会有任何输出
启动devServer指令为:npx webpack-dev-server也可搭建服务器在vue实际项目当中为webpack.dev.conf.js 作用为了要看打包后的内容不能一直进行打包所以要进行自动打包 会用到的是devServer: open: true

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      // 打包其他资源(除了html/js/css资源以外的资源)
      {
        // 排除css/js/html资源
        exclude: /\.(css|js|html|less)$/,
        loader: 'file-loader',
        options: {
          name: '[hash:10].[ext]'
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development',
// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器自动刷新浏览器~~)
  // 特点:只会在内存中编译打包,不会有任何输出
  // 5启动devServer指令为:npx webpack-dev-server
  devServer: {
    // 1项目构建后路径
    contentBase: resolve(__dirname, 'build'),
    // 2启动gzip压缩
    compress: true,
    //3 端口号
    port: 3000,
    // 4自动打开浏览器
    open: true

第六:浏览器兼容css兼容处理方案关键字browserslist webpack兼容问题

利用webpack做浏览器兼容问题在生产环境下 通过工具来做兼容性处理 当设置 通过 设置nodejs环境变量 process.env.NODE_ENV = ‘development’;这个开发环境才会生效

1开发环境 的兼容处理

            //5设置node环境变量:process.env.NODE_ENV = development 才可以激活生产环境
              "development": [
                "last 1 chrome version",
                "last 1 firefox version",
                "last 1 safari version"
              ],

2生产环境 的兼容处理

      // 1生产环境:默认是看生产环境
              "production": [  //2这里包含绝大部分的兼容
                ">0.2%", //3基本上是全部的浏览器
                "not dead", //4不要死的浏览器
                "not op_mini all" //
              ]

在有些实际项目当中在进行设置
生产环境描述

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

// 设置nodejs环境变量
// process.env.NODE_ENV = 'development';

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          /*
            css兼容性处理:postcss --> postcss-loader postcss-preset-env

            帮postcss找到package.json中browserslist里面的配置,
            通过配置加载指定的css兼容性样式
            "browserslist": {
            // 开发环境 -->
            //5设置node环境变量:process.env.NODE_ENV = development
              "development": [
                "last 1 chrome version",
                "last 1 firefox version",
                "last 1 safari version"
              ],
              // 1生产环境:默认是看生产环境
              "production": [  //2这里包含绝大部分的兼容
                ">0.2%", //3基本上是全部的浏览器
                "not dead", //4不要死的浏览器
                "not op_mini all" //
              ]
            }
          */
          // 使用loader的默认配置
          // 'postcss-loader',
          // 修改loader的配置
          {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              plugins: () => [
                // postcss的插件
                require('postcss-preset-env')()
              ]
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: 'css/built.css'
    })
  ],
  mode: 'development' //模式
};

ps压缩等需要靠插件来进行完成这个功能 ,兼容处理需要 先下载npm install --save-dev optimize-css-assets-webpack-plugin

第七:第八js语法检查

 module: {
    rules: [
      /*
        语法检查: eslint-loader  eslint
          注意:只检查自己写的源代码,第三方的库是不用检查的
          设置检查规则:
            package.json中eslintConfig中设置~
              "eslintConfig": {
                "extends": "airbnb-base"
              }
            airbnb --> eslint-config-airbnb-base  eslint-plugin-import eslint
      */
      {
        test: /\.js$/,
        exclude: /node_modules/, //排除node——modules
        loader: 'eslint-loader',
        options: {
          // 自动修复eslint的错误
          fix: true
        }
      }
    ]
  },

第八:js语法检查

js兼容性处理:babel-loader @babel/core

  1. 基本js兼容性处理 --> @babel/preset-env
    问题:只能转换基本语法,如promise高级语法不能转换 例如在IE浏览器

  2. 全部浏览器的js兼容性处理 --> @babel/polyfill 使用@babel/polyfil
    问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了~

  3. 需要做兼容性处理的就做:按需加载 --> core-js 含有按需兼容浏览器 // 按需加载corejs

  module: {
    rules: [
      /*
        js兼容性处理:babel-loader @babel/core 
          1. 基本js兼容性处理 --> @babel/preset-env
            问题:只能转换基本语法,如promise高级语法不能转换
          2. 全部js兼容性处理 --> @babel/polyfill  
            问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了~
          3. 需要做兼容性处理的就做:按需加载  --> core-js
      */  
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          // 1预设:指示babel做怎么样的兼容性处理
          presets: [
            [
              '@babel/preset-env', //1默认情况兼容的处理
              {
                // 2按需加载 
                useBuiltIns: 'usage',
                // 3指定core-js版本
                corejs: {
                  version: 3
                },
                // 4指定兼容性做到哪个版本浏览器
                targets: {
                  chrome: '60',
                  firefox: '60',
                  ie: '9',
                  safari: '10',
                  edge: '17'
                }
              }
            ]
          ]
        }
      }
    ]
  },

第九:入口entry

  entry: 入口起点
    1. string --> './src/index.js'
      单入口
      打包形成一个chunk。 输出一个bundle文件。
      此时chunk的名称默认是 main
    2. array  --> ['./src/index.js', './src/add.js']
      多入口
      所有入口文件最终只会形成一个chunk, 输出出去只有一个bundle文件。
        --> 只有在HMR功能中让html热更新生效~
    3. object
      多入口
      有几个入口文件就形成几个chunk,输出几个bundle文件
      此时chunk的名称是 key

      --> 特殊用法
        {
          // 所有入口文件最终只会形成一个chunk, 输出出去只有一个bundle文件。
          index: ['./src/index.js', './src/count.js'], 
          // 形成一个chunk,输出一个bundle文件。
          add: './src/add.js'
        }

第十:output

 // 文件名称(指定名称+目录)
      filename: 'js/[name].js',
      // 输出文件目录(将来所有资源输出的公共目录)
      path: resolve(__dirname, 'build'),
      // 所有资源引入公共路径前缀 --> 'imgs/a.jpg' --> '/imgs/a.jpg'
      publicPath: '/',
      chunkFilename: 'js/[name]_chunk.js', // 非入口chunk的名称

第十一:devServer配置开发环境

服务器代理 --> 解决开发环境跨域问题在实际vue项目当中proxyTable我们代码通过代理服务器运行然而服务器和服务器没有跨域的问题的

配置开发环境

devServer: {
    // 运行代码的目录
    contentBase: resolve(__dirname, 'build'),
    // 监视 contentBase 目录下的所有文件,一旦文件变化就会 reload
    watchContentBase: true,
    watchOptions: {
      // 忽略文件
      ignored: /node_modules/
    },
    // 启动gzip压缩
    compress: true,
    // 端口号
    port: 5000,
    // 域名
    host: 'localhost',
    // 自动打开浏览器
    open: true,
    // 开启HMR功能
    hot: true,
    // 不要显示启动服务器日志信息
    clientLogLevel: 'none',
    // 除了一些基本启动信息以外,其他内容都不要显示
    quiet: true,
    // 如果出错了,不要全屏提示~
    overlay: false,
    // 服务器代理 --> 解决开发环境跨域问题
    proxy: {
      // 一旦devServer(5000)服务器接受到 /api/xxx 的请求,
      //就会把请求转发到另外一个服务器(3000)
      '/api': {
        target: 'http://localhost:3000',
        // 发送请求时,请求路径重写:将 /api/xxx --> /xxx (去掉/api)
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }

1webpack之proxyTable设置跨域

proxyTable设置跨域

2为什么要使用proxyTable

在平时项目的开发环境中,经常会遇到跨域的问题,尤其是使用vue-cli这种脚手架工具开发时,由于项目本身启动本地服务是需要占用一个端口的,所以必然会产生跨域的问题。当然跨域有多种解决方式,这里就不一一例举,下次弄篇文章单独讲,在使用webpack做构建工具的项目中使用proxyTable代理实现跨域是一种比较方便的选择。

3如何使用proxyTable

还是拿之前使用过的vue-cli举例。我们首先要在项目目录中找到根目录下config文件夹下的index.js文件。由于我们是在开发环境下使用,自然而然是要配置在dev里面:

dev: {
  env: require('./dev.env'),
  port: 8080,
  autoOpenBrowser: true,
  assetsSubDirectory: 'static',
  assetsPublicPath: '/',
  proxyTable: {
    '/api': {
      target: 'http://www.abc.com',  //目标接口域名
      changeOrigin: true,  //是否跨域
      pathRewrite: {
        '^/api': '/api'   //重写接口
      }
    },
  cssSourceMap: false
}
上面这段代码的效果就是将本地8080端口的一个请求代理到了http://www.abc.com这一域名下:
http://localhost:8080/api' ===> 'http://www.abc.com/api'

4关于proxyTable的原理

这个代理实际上是利用http-proxy-middleware这个插件完成的
本地服务器 --》 代理 --》目标服务器 --》拿到数据后通过代理伪装成本地服务请求的返回值 —》然后浏览器就顺利收到了我们想要的数据

第十二:Loader和Plugin的不同?

  • Loader直译为加载器。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力
  • Plugin直译为插件。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果
  • webpack的构建流程是什么?
    在这里插入图片描述

第十三:有哪些常见的Loader和Plugin?他们是解决什么问题的

1 loader

loader解决问题
babel-loader把 ES6 或React转换成 ES5
css-loader加载 CSS,支持模块化、压缩、文件导入等特性
eslint-loader通过 ESLint 检查 JavaScript 代码
file-loader把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
url-loader和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
sass-loader把Sass/SCSS文件编译成CSS
postcss-loader使用PostCSS处理CSS
css-loader主要来处理background:(url)还有@import这些语法。让webpack能够正确的对其路径进行模块化处理
css-loader把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。

2 plugin

插件解决问题
case-sensitive-paths-webpack-plugin如果路径有误则直接报错
webpack-manifest-plugin生产资产的显示清单文件
optimize-css-assets-webpack-plugin用于优化或者压缩CSS资源
mini-css-extract-pluginCSS提取为独立的文件的插件,对每个包含css的js文件都会创建一个CSS文件,支持按需加载css和sourceMap
ModuleScopePlugin如果引用了src目录外的文件报警插件
InterpolateHtmlPlugin和HtmlWebpackPlugin串行使用,允许在index.html中添加变量
ModuleNotFoundPlugin找不到模块的时候提供一些更详细的上下文信息
DefinePlugin创建一个在编译时可配置的全局常量,如果你自定义了一个全局变量PRODUCTION,可在此设置其值来区分开发还是生产环境
WatchMissingNodeModulesPlugin此插件允许你安装库后自动重新构建打包文件

第十四: webpack 的应用

1vue生产发布对应不同api总结

  1. 区分环境
    先找到config 文件下的dev.env.js与prod.env.js她们是生产环境下与发布环境下的1,/config/dev.env.js2/config/prod.env.js
    首先打开dev.env.js文件代码如下

区分环境
添加以下代码

module.exports = merge(prodEnv, {
NODE_ENV: ‘“development”’,
API_ROOT: ‘"//127.0.0.1/api"’ //接口路径
})
​
找到 prod.env.js下面也添加一项代码
​
‘use strict’ module.exports = {
NODE_ENV: ‘“production”’,
API_ROOT: ‘"//www.baidu.com/api"’ //根据自己的项目接口
}
​
然后我们可以在main.js文件设置vue原型,将他设置为全局变量
​
Vue.prototype.baseURL = process.env.API_ROOT;
​
这样我们就配置完成了,可以在需要引用的组件中alert(this.baseURL),就可以看到弹出我们设置好的地址了。
或者直接在main.js中进行判断
​
process.env.NODE_ENV===‘production’?生产地址:开发地址
​
2.生产环境和开发环境的打包
​
1)需要安装cross-env
​
npm install cross-env –save-dev
​
2)在config文件里面新建test.env.js
里面的内容是
​
‘use strict’
module.exports = {
NODE_ENV: ‘“testing”’,
EVN_CONFIG:’“test”’
}
​
3)config中修改prod.env.js文件
​
‘use strict’
module.exports = {
NODE_ENV: ‘“production”’,
ENV_CONFIG:’“prod”’
}
记住NODE_ENV这里是需要添加双引号的,如果去掉了就会报错哦
​
4)config中的index.js 文件中build部分代码修改如下:
​
build: {
prodEnv: require(’./prod.env’),//添加这行
testEnv: require(’./test.env’),//添加这行
// Template for index.html
index: path.resolve(__dirname, ‘…/dist/index.html’),
// Paths
assetsRoot: path.resolve(__dirname, ‘…/dist’),
assetsSubDirectory: ‘static’,
assetsPublicPath: ‘/’,
//以下省略… }
​
5)在build中webpack.prod.conf.js做如下修改:
将
​
const env = require(’…/config/prod.env’)
修改为
const env = config.build[process.env.env_config+‘Env’]
​
6)将build里面的build.js部分做修改:
​
‘use strict’ require(’./check-versions’)()
​
// process.env.NODE_ENV = ‘production’//原始内容,注释掉
​
const ora = require(‘ora’)
const rm = require(‘rimraf’)
const path = require(‘path’)
const chalk = require(‘chalk’)
const webpack =require(‘webpack’)
const config = require(’…/config’)
const webpackConfig = require(’./webpack.prod.conf’)
​
// const spinner = ora(‘building for production…’)//原始内容,注释掉 var
spinner = ora(‘building for ’ + process.env.NODE_ENV + ’ of ’ +
process.env.env_config+ ’ mode…’ )//添加这行
​
7)修改package.json文件(在script里面添加):
​
“scripts”: {
“dev”: “webpack-dev-server --inline --progress --config build/webpack.dev.conf.js”,
“start”: “npm run dev”,
“build”: “node build/build.js”,
“build–test”: “cross-env NODE_ENV=testing env_config=test node build/build.js”,
“build–prod”: “cross-env NODE_ENV=production env_config=prod node build/build.js”
},
​
8)在src文件夹中新建common文件夹,在common里面新建env.js,里面的内容如下:
​
/* * 配置编译环境和线上环境之间的切换
​
以及静态变量
*baseUrl: 域名地址
routerMode: 路由模式
*/let baseUrl = ‘’;
let routerMode = ‘history’;
let DEBUG = false;
let cancleHTTP = [];//取消请求头设置;
if (process.env.NODE_ENV ==
‘development’) { //生产环境走的地址
baseUrl = “协议名://域名:端口号”;
DEBUG = true;
}else if(process.env.NODE_ENV == ‘production’){
//测试环境地址
baseUrl = “协议名://域名:端口号”; //测试地址
DEBUG = false;
}else if(process.env.NODE_ENV == ‘testing’){
//测试环境地址
baseUrl = “协议名://域名:端口号”; //测试地址
DEBUG = false;
}
export default{
baseUrl,
routerMode,
DEBUG,
cancleHTTP }
​
这样baseurl就可以根据环境来变化了,只要在js文件或者在组件里面引用env.js
里面就可以了;
9)想要test环境下则运行:
​
npm run build–test
​
10)想要prod环境下则运行:
​
npm run build–prod
以上是在项目中具体更改

运行项目,打开app时index.html是空白页 在config下面的index,js文件下改下assetsPublicPath:‘./’
在这里插入图片描述

第十五: 如何利用webpack来优化前端性能?

1: 安装

cnpm i react react-dom  -S
cnpm install  webpack webpack-cli webpack-dev-server image-webpack-loader mini-css-extract-plugin purgecss-webpack-plugin babel-loader @babel/core @babel/preset-env @babel/preset-react terser-webpack-plugin html-webpack-plugin optimize-css-assets-webpack-plugin mini-css-extract-plugin qiniu -D

2: 压缩JS

  optimization: {
    minimize: true,
    minimizer: [
      //压缩JS
 +     new TerserPlugin({})
    ]
  },

3: 压缩CSS

  optimization: {
    minimize: true,
    minimizer: [
      //压缩CSS
 +      new OptimizeCSSAssetsPlugin({}),
    ]
  },

4: 压缩图片

      {
        test: /\.(png|svg|jpg|gif|jpeg|ico)$/,
        use: [
          "file-loader",
          {
 +            loader: "image-webpack-loader",
 +            options: {
 +              mozjpeg: {
 +                progressive: true,
 +                quality: 65,
 +              },
 +              optipng: {
 +                enabled: false,
 +              },
 +              pngquant: {
 +                quality: "65-90",
 +                speed: 4,
 +              },
 +              gifsicle: {
 +                interlaced: false,
 +              },
 +              webp: {
 +                quality: 75,
 +              }
 +            }
 +          }
        ]
      }

5: 清除无用的CSS

单独提取CSS并清除用不到的CSS

const path = require("path");
+const MiniCssExtractPlugin = require("mini-css-extract-plugin");
+const PurgecssPlugin = require("purgecss-webpack-plugin");
module.exports = {
  module: {
    rules: [
       {
        test: /\.css$/,
        include: path.resolve(__dirname, "src"),
        exclude: /node_modules/,
        use: [
          {
+            loader: MiniCssExtractPlugin.loader,
          },
          "css-loader",
        ],
      }
    ]
  },
  plugins: [
+    new MiniCssExtractPlugin({
+      filename: "[name].css",
+    }),
+    new PurgecssPlugin({
+      paths: glob.sync(`${PATHS.src}/**/*`,  { nodir: true }),
+    })
  ]
  devServer: {},
};

6: Tree Shaking

  • 一个模块可以有多个方法,只要其中某个方法使用到了,则整个文件都会被打到bundle里面去,tree shaking就是只把用到的方法打入bundle,没用到的方法会uglify阶段擦除掉
  • 原理是利用es6模块的特点,只能作为模块顶层语句出现,import的模块名只能是字符串常量
  • webpack默认支持,在.babelrc里设置module:false即可在production mode下默认开启

7: 代码分割

  • 对于大的Web应用来讲,将所有的代码都放在一个文件中显然是不够有效的,特别是当你的某些代码块是在某些特殊的时候才会被用到
  • webpack有一个功能就是将你的代码库分割成chunks语块,当代码运行到需要它们的时候再进行加载

第十六: 如何对bundle体积进行监控和分析?

  • 是一个webpack的插件,需要配合webpack和webpack-cli一起使用。这个插件的功能是生成代码分析报告,帮助提升代码质量和网站性能

1: 安装

cnpm i webpack-bundle-analyzer -D

const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer')
module.exports={
  plugins: [
    new BundleAnalyzerPlugin()  // 使用默认配置
    // 默认配置的具体配置项
    // new BundleAnalyzerPlugin({
    //   analyzerMode: 'server',
    //   analyzerHost: '127.0.0.1',
    //   analyzerPort: '8888',
    //   reportFilename: 'report.html',
    //   defaultSizes: 'parsed',
    //   openAnalyzer: true,
    //   generateStatsFile: false,
    //   statsFilename: 'stats.json',
    //   statsOptions: null,
    //   excludeAssets: null,
    //   logLevel: info
    // })
  ]
}

{
 "scripts": {
    "dev": "webpack --config webpack.dev.js --progress"
  }
}

2: 先生成文件再分析

webpack.config.js

const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer')
module.exports={
  plugins: [
    new BundleAnalyzerPlugin({
      analyzerMode: 'disabled', // 不启动展示打包报告的http服务器
      generateStatsFile: true, // 是否生成stats.json文件
    }),
  ]
}
{
 "scripts": {
    "generateAnalyzFile": "webpack --profile --json > stats.json", // 生成分析文件
    "analyz": "webpack-bundle-analyzer --port 8888 ./dist/stats.json" // 启动展示打包报告的http服务器
  }
}

npm run generateAnalyzFile
npm run analyz

第十七: 利用缓存

webpack中利用缓存一般有以下几种思路:

  • babel-loader开启缓存
  • 使用cache-loader
  • 使用hard-source-webpack-plugin

1babel-loader

Babel在转义js文件过程中消耗性能较高,将babel-loader执行的结果缓存起来,当重新打包构建时会尝试读取缓存,从而提高打包构建速度、降低消耗

 {
    test: /\.js$/,
    exclude: /node_modules/,
    use: [{
      loader: "babel-loader",
      options: {
        cacheDirectory: true
      }
    }]
  },

2 cache-loader

在一些性能开销较大的 loader 之前添加此 loader,以将结果缓存到磁盘里,
存和读取这些缓存文件会有一些时间开销,所以请只对性能开销较大的 loader 使用此 loader

cnpm i  cache-loader -D
const loaders = ['babel-loader'];
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          'cache-loader',
          ...loaders
        ],
        include: path.resolve('src')
      }
    ]
  }
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐