webpack相关(未完结)

1.module、chunk、bundle的区别

  • module:各个源码文件,webpack中一切建模块。
  • chunk:多模块合并成的,代码块。如:entry、 import()、 splitChunk
  • bundle:最终输出文件

2.webpack性能优化

可以从两方面来着手考虑:打包构建速度、优化产出代码

打包构建速度:

  • 优化babel-loader
    ①开启缓存:?cacheDirectort
    ②明确范围: includeexclude
{
	test: /\.js$/,
	use: ['babel-loader?cacheDirectort'],//开启缓存
	include: path.resolve(__dirname, 'src'),//明确范围
	//  //排除范围,include 和  exclude 两者选一个即可
	// exclude: path.resolve(__dirname, 'node_modules');
}
  • IgnorePlugin
    避免引入无用模块。
    例如:
//避免引入moment 下的 /locale 目录
//plugins配置项中使用webpack中的IgnorePlugin方法(首先得import('webpack'))
plugins: [
	// 忽略 moment 下的 /locale 目录
   	new webpack.IgnorePlugin(/\.\/locale/, /moment/),
]
  • noParse
    避免重复打包
    比如针对react.min.js等已经打包过的文件,不需要重复打包。
    跟IgnorePlugin的区别为:IgnorePlugin直接不引入,代码中没有。noParse引入,但不打包。
module.exports = {
	module: {
		noParse: [/react\.min\.js$/],
	}
}
  • happyPack
    多进程打包
    先安装:npm install happypack。再引入:const happyPack = require('happypack');
modules: {
	rules: [
		{
			text: /\.js$/,
			// 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例
			use: ['happypack/loader?id=babel'],//跟下面的id对应
			incluse: path.join(__dirname, '..', 'src')
		}
	]
},
plugins: [
	// happyPack 开启多进程打包
       new HappyPack({
           // 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
           id: 'babel',
           // 如何处理 .js 文件,用法和 Loader 配置中一样
           loaders: ['babel-loader?cacheDirectory']
       }),
]
  • ParallelUglifyPlugin
    开启多进程压缩js,一般只在生产配置中启用。
    备注:1.webpack内置Uglify巩固压缩JS,但是是单线程的。和happyPack同理。
    2.一般只应用于较大项目中使用,按需使用。

配置:
安装:npm install webpack-parallel-uglify-plugin 引入:const ParallelUglifyPlugin = require('npm install webpack-parallel-uglify-plugin');


plugins: [
		// 使用 ParallelUglifyPlugin 并行压缩输出的 JS 代码
        new ParallelUglifyPlugin({
            // 传递给 UglifyJS 的参数
            // (还是使用 UglifyJS 压缩,只不过帮助开启了多进程)
            uglifyJS: {
                output: {
                    beautify: false, // 最紧凑的输出
                    comments: false, // 删除所有的注释
                },
                compress: {
                    // 删除所有的 `console` 语句,可以兼容ie浏览器
                    drop_console: true,
                    // 内嵌定义了但是只用到一次的变量
                    collapse_vars: true,
                    // 提取出出现多次但是没有定义成变量去引用的静态值
                    reduce_vars: true,
                }
            }
        })
]
  • 自动刷新
    在代码改完保存之后自动打包并刷新页面
    实际中使用webpack devServer就自带自动刷新功能
  • 热更新(自动刷新的升级版)
    自动刷新:整个网页全部刷新,速度较慢,状态会丢失
    热更新:新代码生效,网页不刷新,状态不丢失
    引入:const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin');
    前提是使用devServer。
    涉及entry plugins devServer三个配置项
entry: {
        // index: path.join(srcPath, 'index.js'),
        index: [
            'webpack-dev-server/client?http://localhost:8080/',
            'webpack/hot/dev-server',
            path.join(srcPath, 'index.js')
        ]
    },
plugins: [
  	new HotModuleReplacementPlugin()
],
devServer: {
        port: 8080,
        progress: true,  // 显示打包的进度条
        contentBase: distPath,  // 根目录
        open: true,  // 自动打开浏览器
        compress: true,  // 启动 gzip 压缩

        hot: true,//开启热更新

        // 设置代理
        proxy: {
            // 将本地 /api/xxx 代理到 localhost:3000/api/xxx
            '/api': 'http://localhost:3000',

            // 将本地 /api2/xxx 代理到 localhost:3000/xxx
            '/api2': {
                target: 'http://localhost:3000',
                pathRewrite: {
                    '/api2': ''
                }
            }
        }
    },

另外:需要在入口js文件中增加热更新的逻辑代码:
index.js:

 //增加,开启热更新之后的代码逻辑
 if (module.hot) {
     module.hot.accept(['./math'], () => {//数组中接收:哪些文件需要热更新。一旦该文件内容改变,触发热更新,执行该回调函数。
         
     })
 }
  • DLLPlugin
    动态链接库插件
    webpack已内置DLLPlugin支持,打包出dll文件,DLLRefrtencePlugin:使用dll文件

优化产出代码:

考虑点:

  • 体积更小
  • 合理分包,不重复加载
  • 速度更快、内存使用更少

方式:

  • 小图片base64编码
  • bundle加hash
  • 懒加载
  • 提取公共代码
  • IgnorePlugin
  • 使用CDN加速publicPath
    1.可以在output配置项中添加,将修改所有静态文件 url 的前缀(如 cdn 域名)
    2.也可以在module rules规则配置中,如图片加载:
            {
                test: /\.(png|jpg|jpeg|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        // 设置图片的 cdn 地址(也可以统一在外面的 output 中设置,那将作用于所有静态资源)
                       	publicPath: 'http://cdn.abc.com'  //cdn地址
                    }
                }
            },
  • 使用production
    在mode中开启production。mode: 'production'
    好处:
    1.自动开启代码压缩(不需要自己配置了)
    2.vue React 等会自动删掉调试代码
    3.启动Tree-shaking(会将无用代码删除;必须用ES6 module才能让tree-shaking生效)
    备注:ES6 MOdule 和 Commonjs区别
    1.ES6 Module 静态引入,编译时引入
    2.Commonjs 动态引入,执行时引入
    3.只有ES6 Module才能静态分析,实现Tree-shaking
  • Scope Hosting
    目的:编译过来之后,多个函数合并成一个函数,减少作用域,减少内存cpu的消耗
    好处:代码体积更少,代码可读性更好,创建函数作用域更少
    使用:
    1.引入:const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');
    2.开启插件:
plugins: [
	resolve: {
		//针对 npm中的第三方模块优先采用jsnext:main 中指向的ES6 模块化语法的文件
		mainFields: ['jsnext:main', 'browser', 'main']
	}
	//开启Scope Hosting
	new ModuleConcatenationPlugin();
]

3.babel相关

环境搭建&基本配置

  • 环境搭建
    需要安装一些东西:用package.json配置表示安装哪些:
"devDependencies": {
    "@babel/cli": "^7.7.5",
    "@babel/core": "^7.7.5",
    "@babel/plugin-transform-runtime": "^7.7.5",
    "@babel/preset-env": "^7.7.5"
  },
  "dependencies": {
    "@babel/polyfill": "^7.7.0",
    "@babel/runtime": "^7.7.5"
  }
  • .babelrc配置 presetsplugins
{
    "presets": [
        [
            "@babel/preset-env",//预设看官网,一般就用这个就可以了
            {
                "useBuiltIns": "usage",
                "corejs": 3
            }
        ]
    ],
    "plugins": [//插件 看官网
        [
            "@babel/plugin-transform-runtime",
            {
                "absoluteRuntime": false,
                "corejs": 3,
                "helpers": true,
                "regenerator": true,
                "useESModules": false
            }
        ]
    ]
}

运行:npx babel src/index.js

babel-polyfill

  • 什么是Polyfill
    API补丁

  • core.js 和 regenerator
    core.js是所有API补丁的集合,(处理不了generator函数,generator后被aync跟await取代),所以引入了 regenerator库。

  • Babel7.4之后被弃用,推荐直接使用core.js和regenerator语法

Babel只解析语法,但是像Promise、includes等新API不支持解析,需要使用babel-polyfill来解决。并且不处理模块化。所以webpack跟babel需要一起使用
使用:

引入babel-polyfill:import '@babel/polyfill'
备注:babel-polyfill文件很大,可以配置按需引入。不需要import
配置按需引入:

"presets": [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage",//按需引入
                "corejs": 3//版本号
            }
        ]
    ]

问题:
会污染全局环境,所以要使用babel-runtime

babel-runtime

(功能跟babel-polyfill一样,开发第三方库必须使用babel-runtime)
原理:例如includesAPI,babel-polyfill会执行:Array.prototype.includes = function() { … }。污染全局的includes,而babel-runtime会:Array.prototype._includes = function() { … }。
要安装插件:plugin-transform-runtime、runtime。看pakage.json:

"devDependencies": {
    "@babel/cli": "^7.7.5",
    "@babel/core": "^7.7.5",
    "@babel/plugin-transform-runtime": "^7.7.5",
    "@babel/preset-env": "^7.7.5"
  },
  "dependencies": {
    "@babel/polyfill": "^7.7.0",
    "@babel/runtime": "^7.7.5"
  }

然后在.babelc中的plugins做配置:

"plugins": [
        [
            "@babel/plugin-transform-runtime",//使用plugin-transform-runtime
            {
                "absoluteRuntime": false,
                "corejs": 3,//corejs版本
                "helpers": true,//帮助提示
                "regenerator": true,//是否使用regenerator语法
                "useESModules": false//是否使用ESmodule
            }
        ]
    ]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值