webpack有哪些优点或缺点
webpack是一个模块化的打包工具
优势:
— 可以模块化封装任意资源,适配任意模块体系,适合SPA单页应用的开发
— 插件丰富,可以做很多事情;
— 社区活跃,大多数场景都能找到现有的开源扩展
spa 单页应用程序 ([]()
缺点:
— 不利于初学者,调试很难定位问题
— 配置复杂,babel编译的js代码打包后太大
webpack在使用过程中遇到了哪些问题,以及如何解决
1 打包速度慢,因为在babel-loaders上,babel-loaders特别持久进行句子转换
解决方案:主要使用include和exclusion来包含或排除范围
模块: {
装载机:[{
测试:/.js$/,
加载器:'巴别塔加载器'webpack 同步,
排除:/node_modules/,
询问: {
预设:[“es2015”]
}]
但问题来了。 事实上,这样的增幅并不显着。 使用include可以显着提高速率
模块: {
装载机:[{
测试:/.js$/,
加载器:'巴别塔加载器',
排除:/node_modules/,
包括:/src/,
询问: {
预设:[“es2015”]
}]
2 使用babel进行es6转换时,报错:fileSystem.statSync is not a function
解决方案:
如果 babel-loader >= 7.0.0 那么 webpack >= 2.2.0
如果 webpack > 4.x 则 babel-loader > 7.0
有哪些方法可以避免webpack输出的包过大
1 解压三方库
使用插件optimization.splitChunks配置将第三方库分离打包到vendors.js文件中
像react这样的库的核心代码是627KB,所以如果和我们的源码一起打包的话,体积肯定会很大。所以可以在webpack中设置
入口: {
捆绑包:“应用程序”
供应商:['反应']
插件:{
新的 webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js')
这样打包后就会多一个vendor.js文件,然后我们在引入自己的代码之前必须引入这个文件。例如index.html中
插件配置
插件:[
优化: {
// 找到chunk中的共享模块,将其移除以生成单独的chunk
分割块:{
chunks: "all", // async表示提取异步模块,all表示对所有模块生效,initial表示对同步模块生效
缓存组:{
vendors: { // 提取第三方插件
test: /[\/]node_modules[\/]/, // 指定node_modules下的第三方包
名称:“供应商”,
priority: -10 // 提取优先级
},
utilCommon: { // 提取自定义工具库
名称:“常见”,
minSize: 0, // 将参考模块分隔成新代码文件的最小大小
minChunks: 2, // 表示不同文件等被引用的模块被引用了多少次才可以被分离出来生成新的 chunk
优先级:-20
},
2 代码压缩
webpack自带压缩插件UglifyJsPlugin,只需要在配置文件中引入即可
插件:[
新的 webpack.optimize.UglifyJsPlugin({
压缩:{
警告:假
})
添加该插件后,编译速度会明显变慢,所以通常只在生产环境中启用。
另外,服务器还可以启用gzip压缩,优化效果更加显着
3 代码分割
什么是代码分割? 我们知道,一般加载一个网页都会加载所有的js代码。 但对于Web App来说,我们更想要的是只加载当前UI的代码,而不加载没有被点击的部分。
看似麻烦,但是通过webpack的code split和react router就可以轻松实现。 具体示例请参见React Router Huge Apps官方示例。 不过这里还是要说一下之前配置踩过的坑。
Code split不支持ES6模块系统,因此导出和导入时一定要注意,尤其是导入。 如果导入组件时使用ES6的方式,无论使用CommonJs还是AMD,都会失败,并且不会报错!
当然,我踩这个坑是因为我刚刚使用NodeJS,上手的时候用的是ES6风格。 除此之外,还有一点需要注意的是,生产环境的webpack配置文件中,要添加publicPath
输出: {
路径:xxx,
公共路径:yyy,
文件名:'bundle.js'
否则,webpack加载chunk时路径会错误。
4 设置缓存
对于静态文件,第一次获取后,如果文件内容没有发生变化,浏览器可以直接读取缓存的文件。
那么如果缓存设置太长,需要更新文件怎么办?
打包文件名中添加哈希值
输出: {
路径:xxx,
公共路径:yyy,
文件名:'[名称]-[chunkhash:6].js'
5 所有在开发环境中有用的东西在打包到生产环境时都会被删除。
工程太大后,建设速度很慢。 可以用什么方法来加速呢?
1 使用 HappyPack 加速构建
HappyPack将使用多进程来打包和构建。 使用方法相当简单,但并不是所有的loader都支持。
2 优化完善时的搜索路径
webpack打包后,会有各种路径进行查询和搜索,我们可以添加一些配置,使其搜索速度更快
比如如果方便把模块路径改成绝对路径的话就改一下吧。 如果使用纯模块名称导入,则可以添加一些目录路径。
你还可以善于使用resolve alias来给这个数组起别名来配置
3 不需要打包编译的插件库替换为全局的
比如jQuery插件、react、react-dom等,代码量很多,打包起来可能需要很长时间。
可以直接用标签导入,然后在webpack配置中使用expose-loader或者externals或者ProvidePlugin提供相应的变量供模块内部使用
使用: [{
加载程序:'暴露加载程序'webpack 同步,
选项:'/pre>
}, {
加载程序:'暴露加载程序',
选项:'jQuery'
}]
// @2
外部:{
jquery: 'jQuery'
},
//@3
新的网页包。 提供插件({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
4 热更新热替换
webpack 支持监听模式。 这时需要重新编译时就可以进行增量创建了。 增量创建速度非常快,不到1秒或者几秒就可以重新编译。
注意区分开发环境和线上环境,开发环境支持热更新替换
// 设置开发环境本地服务器实现热更新
开发服务器:{
contentBase: path.resolve(__dirname, 'static'),
// 提供给外部访问
主机:'0.0.0.0',
端口:8388,
// 允许开发服务器访问本地服务器的打包JSON文件,防止跨域
标题:{
'访问控制允许来源': '*'
},
// 设置热替换
热:真实,
// 设置页面导入
内联:真
},
// 文件输出配置
输出: {
// 设置路径,防止开发服务器访问本地服务器相关资源时认为是相对路径
publicPath: ':8188/dist/js/',
},
// 插件配置
插件:[
// 热更新替换
新的网页包。 HotModuleReplacementPlugin()
5 babel-loader 打开缓存
babel-loader执行时,可能会形成一些运行过程中重复的公共文件,导致代码体积大、冗余,同时也会降低编译效率
可以添加cacheDirectory参数或者使用transform-runtime插件尝试
6.使用异步模块加载
这可以看作是减小了模块的体积。 一定程度上也是为用户考虑的。 使用 require.ensure 设置哪些模块需要异步加载,webpack 会将其打包成独立的 chunk。
在某个时刻(例如用户点击查看)这个模块被异步加载执行
$('.bg-input').click(() => {
console.log('点击,加载 async.js')
require.ensure([], 要求 => {
require('./components/async2').log();
require('./components/async1').log();
console.log('加载 async.js 完成');
});
});
5 如何基于webpack进行工程化
1 提高构建速度
— 加速Resolve阶段以加快文件搜索速度
— 加速加载器执行阶段,减少加载器要执行的文件数量
2 优化提升输出
— tree-shaking 删除了冗余代码
代码压缩
js代码压缩
CSS代码压缩
— 拆箱
异步加载
提取第三方库