webpack优化和升级到webpack4y遇到的问题

本文围绕Webpack展开,介绍了优化方法,包括减少打包体积、提高构建速度,如缩小编译范围、开启分析工具等;阐述了Webpack升级到4后的变化及替代插件;还提及TypeScript在React中的使用,以及打包后.map文件相关内容,最后列举了升级Webpack 4遇到的问题和npm创建项目失败的解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

webpack优化

1、就是减少打包体积,避免加载不需要的资源

提高构建速度

  • 缩小编译范围,减少不必要的编译工作,即 modules、mainFields、noParse、includes、exclude、alias全部用起来。
  • 开启enforeExtension
  • dll
  • loader缓存(cacheDirectory)

  • dll
DLLPlugin插件,对不常更新的库,一次打包,存在指定位置,后续直接应用不用再次打包,提高构建速度
  • extension
extension:['.js','.jsx','.ts','.tsx']
在导入语句没带文件后缀时,Webpack 会自动带上后缀后去尝试询问文件是否存在
import './test'
webpack先找test.js
再找test.jsx....直到test.tsx也不存在就报错
所以extension越长,尝试次数越多,所以开启强制enforceExtension


  • loader缓存(cacheDirectory)
loader转换文件为webpack能识别的js文件很慢,所有可以缓存提高转椅速度
test exclude includes

  • 缩小编译范围
const resolve = dir => path.join(__dirname, '..', dir);

// ...
resolve: {
    modules: [ // 指定以下目录寻找第三方模块,避免webpack往父级目录递归搜索
        resolve('src'),
        resolve('node_modules'),
        resolve(config.common.layoutPath)
    ],
    mainFields: ['main'], // 只采用main字段作为入口文件描述字段,减少搜索步骤
    alias: {
        vue$: "vue/dist/vue.common",
        "@": resolve("src") // 缓存src目录为@符号,避免重复寻址
    }
},
module: {
    noParse: /jquery|lodash/, // 忽略未采用模块化的文件,因此jquery或lodash将不会被下面的loaders解析
    // noParse: function(content) {
    //     return /jquery|lodash/.test(content)
    // },
    rules: [
        {
            test: /\.js$/,
            include: [ // 表示只解析以下目录,减少loader处理范围
                resolve("src"),
                resolve(config.common.layoutPath)
            ],
            exclude: file => /test/.test(file), // 排除test目录文件
            loader: "happypack/loader?id=happy-babel" // 后面会介绍
        },
    ]
}



编译瓶颈,

  • bable等loader解析阶段
同 webpack-parallel-uglify-plugin 插件一样,HappyPack 也能实现并发编译,从而可以大幅提升 loader 的解析速度


  • js压缩卡很久
js 压缩是发布编译的最后阶段,通常webpack需要卡好一会,
这是因为压缩 JS 需要先将代码解析成 AST 语法树,
然后需要根据复杂的规则去分析和处理 AST
最后将 AST 还原成 JS,这个过程涉及到大量计算,因此比较耗时

解决办法:用webpack-parallel-uglify-plugin 插件,
由于node单线程,但是可以fork子进程
webpack-parallel-uglify-plugin 能够把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程
从而实现并发编译,进而大幅提升js压缩速度,如下是配置。

减少体积

  • 开启webpack-bundle-analyzer分析,查看资源图
  • antd lodash echarts没有按需加载
  • 提取公共模块
  • 必要的库CDN引用externals

其他脚手架以及实现了,unglfy压缩代码,减少不必要的代码moment

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


webpack升级到4以后变化

  • CommonsChunkPlugin废弃
由 optimization.splitChunks 和 optimization.runtimeChunk 替代,
前者拆分代码,后者提取runtime代码。
原来的CommonsChunkPlugin产出模块时,会包含重复的代码,并且无法优化异步模块,minchunks的配置也较复杂,splitChunks解决了这个问题;

另外,将 optimization.runtimeChunk 设置为true(或{name: “manifest”}),便能将入口模块中的runtime部分提取出来



  • NamedModulesPlugin 废弃,由 optimization.namedModules 替代,生产环境默认开启。
 NamedModulesPlugin: 返回热加载时直接返回更新文件名
[HMR] Updated modules:
[HMR]  - ./example.js
[HMR]  - ./hmr.js
[HMR] Update applied.

没使用:
[HMR] Updated modules:
[HMR]  - 39
[HMR]  - 40
[HMR] Update applied.

  • ModuleConcatenationPlugin 废弃,由 optimization.concatenateModules 替代,生产环境默认开启。
  • optimize.UglifyJsPlugin 废弃,由 optimization.minimize 替代,生产环境默认开启
  • extract-text-webpack-plugin被mini-css-extract-plugin,不支持热更新,所以要引入 css-hot-loader

其他

  • 使用alias(减少导入文件失误)将导入路径映射成一个新的导入路径

  • DLLPlugin插件,对不常更新的库,一次打包,存在指定位置,后续直接应用不用再次打包,提高构建速度

  • lodash

import {chain, cloneDeep} from 'lodash'

  • antd按需加载, (全部加载1.9M,按需记载项目中只有1M)
npm install babel-plugin-import --save-dev //不安装会报错



package.json

 "babel": {
    "presets": [
      "react-app"
    ],
    // 实现按需加载,1.9M的包,按需加载后只用了1.0M
    "plugins": [
        [
          "import",
          {
            "libraryName": "antd",
            "style": true
          }
        ]
    ]
  }

  • Echarts按需加载
var echarts = require('echarts/lib/echarts');
import 'echarts/lib/chart/map';


  • Moment.js locale 打包优化 //脚手架以及做好了
  • webpack-bundle-analyzer,项目打包分析,查看哪些冗余的加载
// webpack.config.prod.js(npm run build生效)
// config/webpack.config.dev.js(npm start生效)
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

config/webpack.config.dev.js
...
plugins: [
    ...
    new BundleAnalyzerPlugin(),
    ...
]
...

typescript在t sx中使用

https://blog.youkuaiyun.com/s2096828/article/details/83744677

@types/react上面时候使用

npm i react

App.jsx

import React from 'react'
import ReactDOM from 'react-dom'

可以正常使用

App.tsx

import React from 'react'
import ReactDOM from 'react-dom'

//会报错,如下:
Cannot find module 'react'
Cannot find module 'react-dom'

因为react 以及react-dom不是使用Ts开发的
Ts不知道React React-dom的类型,以及模块到处了什么,所以要引入.d.ts申明文件



  • index.d.ts (和.eslintrc.js同级)
declare module '@uiw/react-codemirror'
declare module 'react-json-editor-viewer'
declare module 'yamljs'
declare module '@antv/g6'
declare module 'react-mermaid'
declare module 'mermaid'
declare interface List{}

但是直接npm i @types/react

  • App.tsx
import React from 'react'
import ReactDOM from 'react-dom'
import { Component } from 'react

// 就不会报错


babel

https://www.cnblogs.com/tugenhua0707/p/9452471.html

typeScript 在react中使用总结

https://blog.youkuaiyun.com/s2096828/article/details/83744677

打包后的.map文件

项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。

有了map就可以像未加密的代码一样,准确的输出是哪一行哪一列有错


webpack优化

http://louiszhai.github.io/2019/01/04/webpack4/

升级webpack4遇到的问题

问题一

Plugin could not be registered at 'html-webpack-plugin-before-html-processing'. Hook was not found


安装最新版本的html-webpack-plugin-before-html-processing即可解决

npm i html-webpack-plugin@next
npm i html-webpack-plugin@4.0.0-alpha.2
npm i html-webpack-plugin@latest

new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw)

问题二

Tapable.plugin is deprecated. Use new API on `.hooks`

解决办法:

npm install extract-text-webpack-plugin@next


问题三

this.htmlWebpackPlugin.getHooks is not a function


解决

new InterpolateHtmlPlugin( env.raw)// 换成下面的
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw)

问题四

Cannot read property 'ts' of undefined
 @ multi ./config/polyfills.js ./src/index.tsx main[1]

解决

npm i ts-loader@^4.0.0 


问题5

Path variable [contenthash:8] not implemented in this context: static/css/[name].[contenthash:8].css


解决



问题5

Chunk.initial was removed. Use canBeInitial/isOnlyInitial()

解决

webpack-manifest-plugin": "^1.3.2",
升级到webpack-manifest-plugin: "^2.0.4"

npm i webpack-manifest-plugin@^2.0.4


npm create-react-app失败

  • 报错如下

npm WARN enoent ENOENT: no such file or directory

  • 解决办法
1 sudo npm install -g npm // 更新npm
2 sudo npm cache clean -f // 清除npm缓存
3 sudo npm install -g n // 安装n模块
4 n stable
5 sudo npm install -g cnpm --registry=https://registry.npm.taobao.org //安装淘宝镜像
6 sudo cnpm install -g create-react-app

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值