当前位置: 首页 > news >正文

中职教材 网站建设桔子seo

中职教材 网站建设,桔子seo,阿里巴巴做网站需要多少钱,拉萨做网站公司webpack做为一款当下最流行的前端构建工具,一直以来以门槛太高而受人诟病,且没有一个通用的配置适合所有的项目,为此我们不得不开心的(大误:smiley:)手动配置我们的项目,开启我们的配置工程师之路,本文主要是对webpack…

webpack做为一款当下最流行的前端构建工具,一直以来以门槛太高而受人诟病,且没有一个通用的配置适合所有的项目,为此我们不得不开心的(大误:smiley:)手动配置我们的项目,开启我们的配置工程师之路,本文主要是对webpack的一些基础配置的解释和我们能做的一些优化工作,适合有使用过webpack的前端开发者阅读,各位在阅读过程中不妨打开自己的项目来跟着我一起优化。

分割配置文件 dev prod

通常我们的项目会有开发环境和生产环境,而开发环境我们配置的目标是构建更快,模块热替换,能从chrome控制台报错信息对应的源码的错误处(source map)等。生产环境我们更加关注chunk分离,缓存,安全,tree shaking等优化点。 当然对于开发和生产环境的配置文件肯定是不完全相同的,所以我们将不同环境的配置文件分离开,同时将共用部分抽出来,最后使用webpack-merge插件整合。

//参考使用方法
const webpackMerge = require('webpack-merge');
const additionalConfigPath = {development: './webpack.dev.config.js',production: './webpack.prod.config.js'
};
const baseConfig = {};
module.exports = webpackMerge(baseConfig,require(additionalConfigPath[process.env.NODE_ENV])
);复制代码

在下方的优化点中 我会标注这些点适用的环境 dev=开发环境 prod=生产环境

代码分离 prod

代码分离能够将工程代码分离到各个文件中,然后按需加载或并行加载这些文件,也用于获取更小的 bundle,以及控制资源加载优先级

webpack有三种常用的代码分离方法:

  • 入口起点:配置多入口,输出多个chunk。
  • 防止重复:使用 CommonsChunkPlugin 去重和分离 chunk(webpack4虽然废弃,但有代替方法)
  • 动态导入:常用于按需加载的模块分离

入口起点


//多入口配置 最终输出两个chunk
module.exports = {entry: {index: 'index.js',module: 'module.js'},output: {//对于多入口配置需要指定[name]否则会出现重名问题filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist')}
};复制代码

问题所在:入口chunks中如果包含重复的模块,如jquery,那些重复模块都会被引入到各个bundle中

去除重复

对于webpack4 < 4 我们使用CommonsChunkPlugin插件


entry: {"app": "entry-client.js"
}//首先将app入口的公共模块提取出来
new webpack.optimize.CommonsChunkPlugin({name: 'common',filename: '[name].[chunkHash:6].common.js',chunks: ['app']
})//将 vendor runtime分离出来
new webpack.optimize.CommonsChunkPlugin({name: ['vendor','runtime'],filename: '[name].[chunkHash:6].bundle.js',//这个配置保证没其它的模块会打包进 vendor chunkminChunks: Infinity
}),复制代码

chunks 选项代表了从哪个入口分离公共文件,这里我们使用我们项目的主入口 app来分离自定义的公共模块

首先将自定义的公共模块单独抽离出来,这样做的目的是方便我们做缓存,当自定义模块更新时不会影响到vendor文件的hash值。

然后将第三方库文件 和 webpack运行文件分离。

这样我们的vendor就是非常干净的了,只包含第三方库,可以做长效缓存。这个地方需要分离webpack运行文件runtime,因为无论我们是否修改了项目文件,每次build项目时的runtime文件的hash值总是会发生变化的,需要单独打出来。

对于webpack4 我们需要实现同样的目标


// 提前自定义公共模块
optimization: {splitChunks: {chunks: "all",minSize: 20000,//其他入口chunk引用的次数minChunks: 1, //默认使用name + hash生成文件名name: true,//使用自定义缓存组cacheGroups: {//公共模块commons: {name: 'common',//缓存优先级设置priority: 10,//从入口chunk提取chunks: 'initial'},//提取第三方库vendors: {//符合条件的放入当前缓存组test: /[\\/]node_modules[\\/]/,name: "vendors",chunks: "all"},}}
}//提取webpack运行文件
runtimeChunk: {name: 'manifest'
},复制代码

上面的配置大概意思是对所有满足条件的chunk开启代码拆分。

优先级(priority):多个分组冲突时决定把代码放在哪块

通过splitChunks 和 runtimeChunk插件我们能达到同样的拆分和缓存目的

路由组件动态导入

webpack可以将异步加载的组件打包为chunk,同时按需加载此chunk。最为常见是我们的路由组件,我们可以将路由入口组件动态导入以达到异步加载的目的。

异步组件的导入主要有两种方式 1:ES6 stage3的提案 import() 2:webpack 特定的 require.ensure

//import 方式 
const Login = () => {import(/* webpackChunkName: 'Login' */'./Login')
}//require.ensure 方式 
require.ensure([], function(require){require('./Login');
},"Login");//异步组件打包的chunk命名 使用webpackChunkName 或者
//使用require.ensure的第三个参数//对于webpack2/3需要配置chunkFilename来接收配置的name
output: {//非入口 chunk 的名称chunkFilename: '[name].[chunkHash:6].chunk.js'
}//webpack4配置name为true(默认值)
optimization: {splitChunks: {//chunk name由块名和hash值自动生成name: true}
}复制代码

require.ensure 现在依赖于原生的 Promise。如果在不支持 Promise 的环境里使用 require.ensure,你需要添加 polyfill。

普通组件的异步加载

既然我们可以使用import()和require.ensure来动态导入组件那其实在项目中我们更是做到可以基于组件的异步加载。

比如我们的首页是由20个组件组成,但是首屏只会显示15个组件,另外的5个组件可能是一些弹窗,或底部才显示的这种组件,那么我们完全可以将之使用动态导入抽离出来,在需要的时候加载它,如:


//在异步事件中去导入组件
<div onClick={this.showPopUps}>show-popUps
</div>showPopUps = () => {this.popUps = ()=> {import(/*webpackChunkName: 'PopUps'*/'./popUps')}
}复制代码

这样处理的问题在于,我们在点击按钮弹出浮层时会有一定的延时,因为在点击时我们才从服务端去获取组件,用户体验可能不太优秀。

这时我们可以使用一种预测加载的技术prefetch。prefetch提示浏览器这个资源将来可能需要,浏览器会选择==空闲的时间==去下载此资源。prefetch常常用于加速下一次操作。

<link rel="prefetch">
复制代码

兼容性问题:从上述可以得知,prefetch时基于浏览器实现的,存在一定的兼容性问题,在safari上还没由得到支持。

在不支持的浏览器中并不会影响我们页面的功能

使用:preload-webpack-plugin 使用条件:webpack > 2.2 且需要使用 html-webpack-plugin


plugins: [new HtmlWebpackPlugin(),new PreloadWebpackPlugin({rel: "prefetch",as: 'script',//包含了哪些chunk,默认值为"asyncChunks"include: 'asyncChunks'})
]//最终效果类似这样
<link rel="prefetch" as="script" href="chunk.d15e.js">复制代码

对于.css结尾的文件 as=style,.woff2结尾的文件as=font,否则as=script,当然你可以像上方那样给一个确定的值。

对于include的值,其实我们并不是需要所有的异步chunk都使用prefetch,所以我们需要重设include的值,像这样:


//1 给定需要prefetch的块的名字(chunkName)
include: ["PopUps","Login"]//2 或者在动态导入时指定Prefetch
this.popUps = () => {import(/* webpackChunkName: 'PopUps', webpackPrefetch: true */'./PopUps')
}复制代码

Loader dev prod

为Loader指定作用范围可以加快我们的构建速度,提升开发体验。

{test: /\.jsx?$/,use: ["babel-loader"],exclude: /node_modules/
}
//or
{test: /\.jsx?$/,use: ["babel-loader"],include: /src/
}复制代码

webpack解析(resolve) dev

resolve的部分配置过多项,会导致webpack搜索范围变大,效率下降,如没有特殊需求,可以保持默认配置保持开发体验。

//解析模块时应该搜索的目录
modules: ["node_modules"] //default//自动解析确定的扩展,不宜过多
extensions: [".js", ".json"] //default//解析目录时要使用的文件名,不宜过多
mainFiles: ["index"] //default
复制代码

webpack 外部扩展(Externals) dev prod

externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法,什么意思呢?顾名思义,externals可以排除掉我们打包结果中某些依赖:

//排除react 我们打包后的bundle中没有react了
externals: {//将react指向一个全局变量 reactreact: "react"
}//这里的 "react" 会直接去全局变量中寻找
import react from "react"复制代码

这种设置通常用于==library==开发人员,你的library依赖了react,同时使用了你的库的开发人员也依赖了react,最终会造依赖你的库的用户bundle中react被重复打包。

你应该做的是在你的library中将外部依赖放到externals中排除掉,然后将你的依赖暴露给使用你的库的用户,最后你的library应该从外部获取这些扩展依赖,而不是一股脑打包进你自己的bundle中。当然这个依赖在用户的环境中必须存在且可用。

问题所在:对于从一个依赖目录中,调用的多个文件,使用externals 无法一次排除;

import one from 'react/one';
import two from 'react/two';//上面这种情况只能一个个匹配,或者这通过正则匹配
externals: ['react/one','react/two',/^react\/.+$/
]
复制代码

这里不得不提的是npm依赖管理中的peerDependencies,它的作用正是将我们library中依赖的库暴露给用户的,若是用户没有安装我们库中的必需依赖,npm会抛出错误。

当然如果你不是一个library开发人员,你同样可以使用externals来排除项目中的外部依赖,然后通过其他方式引入成为一个全局变量的方式来优化打包速度。

Dlls 优化构建速度 dev

webpack在每次build时都会将整个项目重新构建一遍,不管这个文件是否发生了改变(当然若文件未更改hash值不变),但是其实我们所依赖的三方库更改并不频繁,若是将三方库抽离出来单独构建,将构建好的目标和构建生成的json对照文件引如我们的项目,这样不用每次都去打包这些代码。

使用 DllPlugin 将更改不频繁的代码进行单独编译。这将改善引用程序的编译速度,即使它增加了构建过程的复杂性。


//新建 webpack.dll.conf.js
module.exports = {entry: {vendor: [react, ...]},output: {filename: 'dll.[name].js'},plugins: [new webpack.DllPlugin({path: '[name]-manifest.json'})]
}//webpack.base.conf.js
const manifest = require('./vendor-manifest.json')plugins: [new webpack.DllReferencePlugin({manifest})
]复制代码

最后需要手动将生成的dll.[name].js引入到html文件中去,当然这一步骤可以用assets-webpack-plugin插件优化。

首发原文地址

原文https://juejin.im/post/5bf8166c518825719f208f59

http://www.lbrq.cn/news/2428489.html

相关文章:

  • 珠海科技网站建设网站seo诊断
  • 深圳做网站比较好的公司竞价
  • 电商拿货平台seo关键词有哪些类型
  • 网站建设流程图2024年重大政治时事汇总
  • 天津做网站的费用网络推广平台大全
  • 乐山网站制作设计公司企业营销策划书范文
  • 外贸网站怎么做优化大师
  • 网络 网站深圳网络营销策划公司
  • 源码出售网站怎么做网站平台做推广
  • 搜点济南网站建设怎么做网络广告推广
  • 用jsp源码做网站网推拉新app推广接单平台
  • 十大免费行情软件网站下载nba最新消息球员交易
  • 日照网站建设价格如何制作简易网站
  • wordpress禁止新建福州短视频seo推荐
  • 网站编辑给续南明做的封面有必要买优化大师会员吗
  • 济源网站建设网络营销项目策划
  • 做赌博黑网站赚钱么么长春seo排名优化
  • 建设局特种作业网站郑州seo排名工具
  • 一级a做爰片在线网站佛山企业用seo策略
  • ps做网站导航条专业网站推广优化
  • 做公司网站的必要性seo推广培训学费
  • 米拓建站怎么样广州网络推广seo
  • 南宁企业网站推广技巧百度网站怎么优化排名
  • 哈尔滨企业网站建设报价百度指数什么意思
  • 网站设计与网页制作项目教程安顺seo
  • 兰州网站建设怎么选公关公司提供的服务有哪些
  • 定制高端网站互联网营销怎么做
  • 苏州网站建设设计制作公司怎么样天天外链官网
  • 深圳有做网站最近价格?西安百度公司官网
  • 青岛公司网站建设价格杭州网站建设网页制作
  • [LLM]Synthetic Visual Genome
  • Golang避免主协程退出方案
  • 【C语言进阶】动态内存管理(1)
  • 分布在内侧内嗅皮层(MEC)的边界细胞对NLP中的深层语义分析的积极影响和启示
  • SmartETL循环流程的设计与应用
  • 计算机网络:概述层---计算机网络的性能指标