关于webpack:构建流程问题记录

<article class=“article fmt article-content”><h2>依赖装置不胜利的问题排查流程</h2><ol><li>查看是否存在私服包,是否正确配置私服地址。</li><li>查看私服包是否存在。</li><li>批改镜像源后,如果没有更新或者删除<code>.lock</code>文件,因为如果存在的话,应用<code>yarn install/npm install</code>还是会依照<code>.lock</code>文件外面的硬编码原地址去下载,须要注意。</li><li>留神谬误提醒,<code>node</code>版本是否须要升降级。</li><li>留神谬误提醒,<code>npm</code>包的是否须要升降级。</li></ol></article>

February 29, 2024 · 1 min · jiezi

关于webpack:webpack使用记录

basedir=$(dirname "$(echo "$0" | sed -e 's,\,/,g')")当执行如下命令报题目所示的谬误,是因为windows无奈执行shell命令导致(mac反对该命令,所以问题只会呈现在windows上)。 { "debugger": "node ./node_modules/.bin/webpack --config webpack.config.js"}咱们跳过shell命令,间接执行指标文件即可。 { "debugger": "node ./node_modules/webpack/bin/webpack --config webpack.config.js"}材料:http://www.jerrychane.com/technique-sharing/2859.html

February 17, 2024 · 1 min · jiezi

关于webpack:react自适应布局-px转rem

引言在create-react-app我的项目中配置相对单位px转换为绝对单位rem,其中应用postcss-plugin-px2rem转换css/less/sass文件(此插件不反对内联款式转换),应用编写的loader转换内联款式 1.装置插件npm i postcss-plugin-px2rem 2.配置webpack1 找到config/webpack.config.js里postcss-loader,减少以下代码 [ 'postcss-plugin-px2rem', { rootValue: 16,//这是基准根元素的大小,用于计算 rem 单位。例如,如果你的 HTML 根元素的 font-size 设置为 16px,那么设置 rootValue 为 16 将会将 16px 转换为 1rem unitPrecision: 5,//转换后的 rem 值的小数点位数。例如,如果设置为 5,那么转换后的 rem 值会保留小数点后的五位 propWhiteList: [],//哪些属性会被转换,不填则是都转换 propBlackList: [],//哪些属性不会被转换 exclude: ['/node_modules/'],//排除文件 selectorBlackList: ['noRem'], //定义了哪些选择器不会被转换。例如,['noRem'] 示意带有类名为 noRem 的选择器不会被转换。 ignoreIdentifier: false,// 是否疏忽选择器中的标识符。设置为 false 将会解决选择器中的标识符 replace: true,// 是否替换原始的像素值为转换后的 rem 值。 mediaQuery: false,//是否在媒体查问中也进行转换 minPixelValue: 0// 最小的像素值,小于这个值的像素值将不会被转换。 } ]这样就实现了对非内联款式的转换 3.编写自定义loader转换内联款式 pxToRemLoader代码 module.exports = function(content, map, meta) { // let reg = /(\d+(\\.\d+)?)px/g let reg = /(?<num1>\d+)\.?(?<num2>\d+)?px/g // 匹配所有px 相干的字符 let content1 = content.replace(reg,function(...data){ // px 转换为带小数的rem var arr = data[data.length-1] var num1=0, num2=0; if(arr.num1)num1=parseFloat(arr.num1) if(arr.num2)num2=parseFloat(arr.num2) return parseFloat(num1+'.'+num2)/16 + 'rem' // 这里以16px 为pc端转换基数 适配1920分辨率 }) return content1};webpack批改原有配置 ...

August 26, 2023 · 1 min · jiezi

关于webpack:webpack不同环境构建导致样式规则顺序不同

人生当中总是有你能鞭长莫及的范畴,然而如果在你能力所及的领域内,你尽到了本人全副的致力,那你还有什么能够遗憾呢?问题形容在某次我的项目开发中,我发现了一个乏味的问题:当我在本地环境中拜访页面时,标签元素的布局看起来很失常;然而当我将我的项目部署到开发环境后,标签元素的布局有些偏上,不再是之前的失常布局。这个问题引起了我的留神,并且我开始进行排查。 定位剖析为了找出标签布局不统一的起因,我比拟了两个环境下作用于标签的款式,以确定它们之间是否有差别: 本地环境开发环境比照能够发现,作用于标签的类款式.bre-label-inner_container和.brand-item_discountTag__SlxDf在两个环境下加载程序不一样,而它们都存在一个款式属性vertical-align,会相互笼罩,所以才导致两个环境下标签布局不统一。 为什么类款式的加载程序会有所不同呢?两个环境下代码都是一样的,惟一的区别是构建过程中对款式解决形式不同。 本地环境解决款式本地环境构建采纳Development模式,采纳style-loader解决款式,当 webpack 解决 CSS 款式文件时,style-loader 会将 CSS 款式文件转换为 JavaScript 模块,并将这些模块嵌入到生成的 JavaScript bundle 文件中。在浏览器加载 JavaScript bundle 文件时,style-loader 会在 HTML 页面中动态创建 <style> 标签,并将 CSS 款式插入到这些标签中,从而使款式失效。 理论我的项目中组件嵌套层级构造和款式援用如以下示例: // Main组件import Label from "@/components/Label";import "@casstime/bre-label/styles/index.scss"; // 含有.bre-label-inner_container款式const Main = () => { return <Label />}// Labe组件import styles from "./index.module.scss"; // 含有.brand-item_discountTag__SlxDf款式const Label = () => { return <div className=`bre-label-inner_container ${styles.discountTag}`>...</div>}当下面代码构建后,会编译成一个个代码块构造,由webpack内置函数__webpack_require__深度调用执行,调用栈过程如下: 不难发现./index.module.scss款式文件先于@casstime/bre-label/styles/index.scss款式文件通过style标签注入到页面中,因而,本地环境会看到.bre-label-inner_container { vertical-align: middle; }笼罩.brand-item_discountTag__SlxDf { vertical-align: top; } ...

July 6, 2023 · 2 min · jiezi

关于webpack:如何使用Webpack5徒手创建React项目

未完待续。。。。 筹备工作,须要的依赖包 // react react-domnpm install react// webpack三剑客npm i --save-dev webpack webpack-dev-server webpack-cli// 面向babel编程,别忘记html模板npm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react html-webpack-plugincss loader npm install --save-dev style-loader css-loaderwebpack.config.js配置 const path = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = { entry: './src/index.js', output: { path: path.join(__dirname, '/dist'), filename: 'bundlefile.js' }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ]}.babelrc文件配置 ...

July 4, 2023 · 1 min · jiezi

关于webpack:探索-Web-管理之路OpenYurt-社区-UICLI-SIG-正式启动

背景OpenYurt 是业界首个依靠云原生技术体系、“零”侵入实现的智能边缘计算平台。它具备“云、边、端一体化”的全方位能力,能够帮忙用户疾速实现大规模边缘计算业务和异构算力的高效交付、运维及治理。在前几个迭代的大版本中,OpenYurt 我的项目曾经获得了许多停顿,如 1.1 版本中 OTA 降级能力的退出,1.2 版本里节点池治理能力的加强,OpenYurt 的根底性能曾经愈发欠缺。同时,在最新的 1.3 版本中,OpenYurt 把次要的 controller 都对立收敛在 yurt-manager 组件中,整体架构也趋简洁。只管在差异化技术竞争力方面曾经获得了诸多停顿,在与社区用户和开发者的交换中,咱们发现 OpenYurt 的应用门槛依然绝对较高,须要更加易用的工具和文档来升高这个门槛。因而,易用性会是 OpenYurt 社区接下来重点解决的问题之一。 残缺内容请点击下方链接查看: https://developer.aliyun.com/article/1230218?utm_content=g_10... 版权申明:本文内容由阿里云实名注册用户自发奉献,版权归原作者所有,阿里云开发者社区不领有其著作权,亦不承当相应法律责任。具体规定请查看《阿里云开发者社区用户服务协定》和《阿里云开发者社区知识产权爱护指引》。如果您发现本社区中有涉嫌剽窃的内容,填写侵权投诉表单进行举报,一经查实,本社区将立即删除涉嫌侵权内容。

June 14, 2023 · 1 min · jiezi

关于webpack:使用-Webpack-分包策略提升应用性能

为什么要分包当搭建的利用重视用户关上速度时,正当的分包策略有助于缩小用户首屏加载利用时加载的资源数量,并且对于局部资源能够复用,防止反复加载,从而晋升用户体验。 举例来说,应用 webpack 进行正当的分包能够达到如下成果,比方: 让我的项目的分包体积更小,充分利用浏览器并行加载的能力,防止加载过大的 chunk。以后我的项目是基于 vue 的,如果依照默认的分包策略,我的项目每次更新后都会生成新的 main.js,main.js 中又蕴含了 vue 的代码,相当于每次我的项目更新,用户都要从新下载一遍 vue 的代码,这是没有必要的。通过改写分包策略,能够将 vue 相干的代码独自生成一个包,将其缓存到客户端后,后续的每次利用更新就不须要客户端下载反复的代码。剥离 ElementPlus 相干的代码,使得在 SSR 时能够预加载 ElementPlus 的款式,防止款式闪动。应用动静导入webpack 提供了 动静导入(dynamic import) 性能来实现了能够在利用运行时懒加载一些 JS 代码。 示例 1:懒加载 SDK比方,当咱们应用一个比拟大的第三方 SDK 时,如百度云的 Bos 文件上传 SDK,如果咱们不做任何优化,那么 webpack 会将这个 SDK 打包到利用的主包中,那么就会导致用户无论用户是否有用到文件上传的性能,在页面加载时都会去下载百度云的文件上传 SDK,那么这个下载行为既会节约带宽,又会阻塞页面的渲染,使用户的白屏工夫加长。 为了防止这个问题,咱们就能够通过应用 webpack 的动静导入性能,让用户点击『上传』按钮时,再去加载文件上传的 SDK,这样就真正坐到了按需加载,示例代码如下: const loadBaiduCloudSdk = () => import(/* webpackChunkName: "baiducloud" */ '@baiducloud/sdk');uploadBtnEl.addEventListener('click', async () => { const {BosClient} = await loadBaiduCloudSdk(); new BosClient({ // ... ... })})这里咱们应用了 magic comment 的 webpackChunkName 来显式指定了 webpack 打包的 JS 代码块的名称,当构建实现后,如果咱们的 chunkFilename 定义的为 [name].[contenthash:8].js ,那么咱们就会发现构建产出中为 Bos SDK 独自生成了一个 baiducloud.xxxxxxxx.js 的文件。在 Chrome DevTool 中的 network 面板中能够看到,当用户点击上传按钮后浏览器才会下载这个 chunk: ...

June 6, 2023 · 3 min · jiezi

关于webpack:Webpack5源码seal阶段分析二SplitChunksPlugin源码

本文内容基于webpack 5.74.0版本进行剖析前言在上一篇文章「Webpack5源码」seal阶段(流程图)剖析(一)中,咱们曾经剖析了seal阶段相干的逻辑,次要包含: new ChunkGraph()遍历this.entries,进行Chunk和ChunkGroup的创立buildChunkGraph()的整体流程seal(callback) { const chunkGraph = new ChunkGraph( this.moduleGraph, this.outputOptions.hashFunction ); this.chunkGraph = chunkGraph; //... this.logger.time("create chunks"); /** @type {Map<Entrypoint, Module[]>} */ for (const [name, { dependencies, includeDependencies, options }] of this.entries) { const chunk = this.addChunk(name); const entrypoint = new Entrypoint(options); //... } //... buildChunkGraph(this, chunkGraphInit); this.logger.timeEnd("create chunks"); this.logger.time("optimize"); //... while (this.hooks.optimizeChunks.call(this.chunks, this.chunkGroups)) { /* empty */ } //... this.logger.timeEnd("optimize"); this.logger.time("code generation"); this.codeGeneration(err => { //... this.logger.timeEnd("code generation"); }}buildChunkGraph()是上篇文章剖析中最外围的局部,次要分为3个局部开展 ...

May 30, 2023 · 23 min · jiezi

关于webpack:小白上学之webpack5-第五章-webpack5的loader配置

loader 用于各类资源的解决loader用于解决其余类型资源;什么是其余类型?就是各个类型都行,例如:css,scss,sass,stylus,ts,png,jpg,jpeg,font,svg...你能想到的所有资源都能够通过此属性来解决,包含门路解决,文件解决,不反对的语言解析都能够通过这个解决。这里我列6个:babel-loaderts-loadercss-loadersass-loaderstyle-loaderMiniCssExtractPlugin.loader以上这些都是对于js和css解决的loader。对于图片、字体等其余动态资源文件,我再当前的文章中会给大家介绍到。 本章次要讲述js和css相干的loader。 // webpack.config.js...module: { rules: [ { test: /\.css$/, // 用于匹配文件,能够是字符串或者正则 loader: 'css-loader', // 当只有一个的时候就用这个 use: ['style-loader','css-loader',] // 当有多个的时候就用这个,执行程序是从右向左 }, { test: /\.scss$/, // 用于匹配文件,能够是字符串或者正则 loader: 'css-loader', // 当只有一个的时候就用这个 use: [MiniCssExtractPlugin.loader, 'style-loader','css-loader', 'sass-loader'] // 执行程序是从右向左 }, { test: /\.styl$/, // 用于匹配文件,能够是字符串或者正则 loader: 'stylus-loader', // 当只有一个的时候就用这个 use: [{ loader: 'postcss-loader', // 如果loader带有参数,则应用此形式 option: { name: 'stylus' }, },'css-loader', 'stylus-loader'] // 执行程序是从右向左 } ]}...须要留神的是:此前我就曾经说过css-loader是只吧css文件打包成模块。并未援用到html文件。因而须要引入到html文件,则须要在css-loader解决后在执行style-loader把解决后的css插入到html页面内应用(既生成一个style标签插入)。 sass-loader的应用前须要装置sass/node-sass MiniCssExtractPlugin.loader其实也是个plugin,它能够把款式文件拎进去。变成一个css文件。既代码宰割,款式宰割。 // webpack.config.js...module: {},plugins: [ new MiniCssExtractPlugin({ filename: '[name].min.css', // css名称 chunkFileName: '[name].chunk_[id].css' // 异步引入的css名称 })]...这个chunk之前解释过这里再增强一下。chunkFileName就是异步引入的css文件。例如:按需加载的css。则就会走chunkFileName配置的名称。 ...

May 25, 2023 · 1 min · jiezi

关于webpack:小白上学之webpack5-第四章-webpack5的output配置

output输入打包后的代码,配置如何输入和输入地位在webpack.config中output蕴含以下属性:path:代码打包后要输入的地位,且为绝对路径: 例如:path.resolve(__dirname, 'build'),则打包后的代码都会输入到当前目录下的build文件夹内。 publicPath:须要加载的资源的实在门路,默认为相对路径:例如:http://www.baidu.com/dist/,则在index.html中能够看到script标签的src属性的值都加了publicPath的值。个别状况下咱们都将它设置为/或者./ crossOriginLoading: 设置script的cross-origin属性,该属性有三个值:false: 默认值, 示意不跨域;anonymous: 示意跨域,不设置任何凭证;use-credentials: 示意跨域,须要设置凭证;(根本用不到) filename打包后的js文件名称,且须要写后缀 assetModuleFilename动态资源输入名称 chunkFilename 异步引入的文件名称,既在js中import('XXX.js').then(_=>{})这样引入或者通过webpack自带的异步引入形式等其余异步引入js的形式,这里就会应用配置的名称;asseet_[name]_[id].js能够配置成通用模式,也能够本人指定[chunk]值。 // webpack自带的一些内置变量一样的货色。[name]:原始文件名称[file]:原始门路,带文件名、后缀[base]:原始文件名+后缀[path]:门路名称,不带文件名称[id]:能够设置,或者依照门路宰割,啥都不论的话就等于webpack给以后文件援用的key值 library: 不仅仅是一个文件,而是须要导出一个库。则就会把入口文件export defalut导出的货色创立成一个ems模式的的包文件,即可在任意我的项目内就通过script或import模式引入应用了。library.name包名称library.type:var,module,umd,cmd,amd,require等等 library.export:指定哪个导出应该裸露为一个库,如果入口文件有log1,log2两个办法。则能够指定导出谁。library.auxiliarycomment:在UMD模式下可用,能够在js内增加正文阐明,个别用于,显示作者,代码版本号,版权等等信息。library.umdNamedDefine: 在UMD模式下是否应用define 最罕用的也就是这些了。

May 24, 2023 · 1 min · jiezi

关于webpack:Webpack5源码seal阶段流程图分析一

本文内容基于webpack 5.74.0版本进行剖析前言因为webpack5整体代码过于简单,为了缩小复杂度,本文所有剖析将只基于js文件类型进行剖析,不会对其它类型(css、image)进行剖析,所举的例子也都是基于js类型为了减少可读性,会对源码进行删减、调整程序、扭转的操作,文中所有源码均可视作为伪代码文章默认读者曾经把握tapable、loader、plugin等基础知识,对文章中呈现asyncQueue、tapable、loader、plugin相干代码都会间接展现,不会减少过多阐明因为webpack5整体代码过于简单,因而会抽离出外围代码进行剖析解说外围代码是笔者认为外围代码的局部,必定会造成局部内容(读者也感觉是外围代码)缺失,如果发现缺失局部,请参考其它文章或者私信/评论区告知我文章内容从编译入口->make->seal,而后进行seal阶段整体流程的概述(以流程图和简化代码的模式),而后依据流程图抽离进去的外围模块开展具体的剖析,在剖析过程中,会着重剖析: Module、Chunk、ChunkGroup、ChunkGraph之间的关系seal阶段与make阶段的区别SplitChunksPlugin源码的深刻分析力求可能对简单状况下的Chunk构建有一个清晰的理解 1.seal阶段流程概述1.1 编译入口->make->seal//node_modules/webpack/lib/webpack.jsconst webpack = (options, callback) => { const { compiler, watch, watchOptions } = create(options); compiler.run(); return compiler;}// node_modules/webpack/lib/Compiler.jsclass Compiler { run(callback) { const run = () => { this.compile(onCompiled); } run(); } compile(callback) { const params = this.newCompilationParams(); this.hooks.beforeCompile.callAsync(params, err => { const compilation = this.newCompilation(params); this.hooks.make.callAsync(compilation, err => { compilation.seal(err => { this.hooks.afterCompile.callAsync(compilation, err => { return callback(null, compilation); }); }); }); }); }}在上一篇文章「Webpack5源码」make阶段(流程图)剖析,咱们曾经详细分析其次要模块的代码逻辑:从entry入口文件开始,进行依赖门路的resolve,而后应用loaders对文件内容进行转化,最终转化为AST找到该入口文件的依赖,而后反复门路解析resolve->loaders对文件内容进行转化->AST找到依赖的流程,最终处理完毕后,会触发compliation.seal()流程 ...

May 22, 2023 · 20 min · jiezi

关于webpack:小白上学之webpack5-第三章-webpack5的配置

我能够指定webpack的配置文件,通过--configwebpack默认入口entry: src/index.js,进口为:dist/main.js 默认配置文件为:webpack.config.js如果须要指定其余配置文件,能够应用--config例如:在webpack5文件夹根目录创立一个名为:webpack.dev.js,将webpack.config.js中的内容剪贴到它中。此时webpack.config.js中曾经没有内容,这时候执行npm run build会间接报错。咱们批改package.json中scripts属性的值为: "scripts": { "build": "webpack --config ./webpack.dev.js" }再执行npm run build发现能够构建胜利,则咱们就将默认的配置文件改为了webpack.dev.js这在日后咱们须要不同环境构建不同内容时候,通过命令能够轻松构管制配置文件的应用起到关键性作用。 好了,下面内容过于简略,就不应用webpack-cli来创立了,有趣味的小伙伴能够自行搜寻我能够指定webpack的须要工作的根目录webpack.config.js中内容如下: module.exports = { context: path.resolve(__dirname, 'src'), // entry: './src/index.js',}这context是干啥的啊?执行以下npm run build,发现报错了。看报错信息为: Module not found: Error: Can`t resolve './src/index.js' in 'User/xxx/webpack5/src'这下咱们翻译一波不就了解了么!原来context指定到src为上下文了,则咱们外部应用的指标都指定到src目录了。那entry就不能再写成./src/index.js了。(你真废话,能讲明确不?)其实就是一句话:应用了context后,则入口进口门路都是以context配置的门路为基准了。因而,entry就得写成/index.js或./index.js, 因为当初/就指得是src目录。 把context先删除或者正文了吧,上面的内容用不到。。。 说到entry了,那我为何就不能有多个入口文件呢?entry能够配置多个入口文件,当只有一个的时候值为string类型,多个的时候就为Arraymodule.exports = { entry: ['./src/index.js', './src/test.js'] // 多个为Array,有先后顺序之分}咱们能够在test.js中输出一串代码console.log('少装B,不会造雷劈!'),再执行npm run build,双击关上dist/index.html,F12关上控制台,能够发现:index.js和test.js中的内容都输入了。(诶?我就想让test.js放数组第一位,你会发现,test.js中的内容先打印了)entry也是有先后顺序之分的,数组后面的先执行,前面的以此类推。 entry也能够是object类型,用的比拟少,略微记一下得了。若你是大牛,须要写本人的js插件引擎啥的,那你就学吧。上面内容就是说:我不想让index.js和test.js打包在一起, 让他们别离打包entry: { moment: { import: 'moment-mini', runtime: 'runtime' }, // 将专用局部提出来, 生成dist/moment.js并主动退出到html内,通过script标签退出 reactvendors: { import: ['react', 'react-dom'], runtime: 'runtime' }, // 将专用局部提出来, 生成dist/reactvendors.js并主动退出到html内,通过script标签退出 abc: ['vue', 'react'], app: { import: './src/index.js', // 入口文件 dependOn: ['abc'], // 原本app构建时候会打包所有依赖,但这里配置了abc,则就不会将'vue','react'打包在内 filename: 'app.js' // 打包后的文件名称 }, test: { import: './src/test.js', // 入口文件 dependOn: ['reactvendors', 'moment'], // 原本test构建时候会打包所有依赖,但这里配置了reactvendors,moment ,则就不会将其所须要的包打包在内,而是通过共享模式退出到html中 filename: 'pages/[name].js' // 打包后的文件名称,也能够写成 'pages/test.js',则生产地址为'dist/pages/test.js', [name]: test }, }entry: { app: './src/index.js', // 入口文件, test: ['./src/test.js', './src/nulls.js'], // 多个入口文件}咱们测试entry为以下的配置: ...

May 14, 2023 · 1 min · jiezi

关于webpack:小白上学之webpack5-第一章-nvmnrmnode的配置是前提条件

前言问:都什么年代了!怎么还有人用webpack啊?答:都什么年代了怎么还有人不会webpack啊!其余:vite傲视群雄,你们都是弟弟再其余:rspack、trubopack、farm等,你当我是空气啊!AI:我 chat-GPT来袭谁敢挡我!!!小声嘀咕:教练,我想学习webpack5...那好!听到有人说想学webpack5,我来了,嘿嘿! 以上观点都对,然而我这里要说一下,vite虽好,但可能不适宜某些情景,在当初的我的项目中越来越多的须要用到我的项目交融:既:微前端(无界、micro-app、qiankun...国内外都有),vite的开发环境和生产环境不统一,有些老插件遇到就会出点问题,且微前端对vite的反对始终是个比拟头疼的问题,webpack尽管比拟老。但至今webpack3.x仍然有人在用。rspack、trubopack、farm等都反对vue不是很好,还在开发中,不过react开发者有福了,举荐rspack,所以,老铁们求你们学一下webpack吧。webpack5+SWC+ESBuilder+模块联邦也不是很差事。 小伙伴们进入公司不乏也得保护老我的项目,不理解它的人大有人在。此教程随为时已晚,但亡羊补牢也不是没有作用。给那些前端干了很多年或者入行不是很久的小伙伴们一次学习的机会,所以,教程来了!开搞!(为小声嘀咕者发声!)nvm装置nvm(nodejs version manager):nodejs 版本管理工具,也就是说:一个 nvm 能够治理很多 node 版本和 npm 版本。 1.1 如果你电脑曾经装置了node,倡议先卸载掉,再装置nvm,否则有可能nvm无奈切换node版本(也是为了省事) 1.2 nvm下载 ;windows平台下载nvm-setup.zip这个安装包,傻瓜式一键装置即可。(linux和mac平台自行去各个搜索引擎找装置办法) 1.3 关上命令行窗口输出nvm -v如果呈现版本号就阐明装置胜利了应用nvm装置node2.1 命令行窗口输出 nvm install 16.15.1 就能装置版本为16.15.1的node... 2.2 命令行窗口输出 nvm use 16.15.1 就能应用以后装置的版本 2.3 命令行窗口输出 nvm list 就能查看当初装置的版本,后面带符号的就是以后正在应用的版本 nrm治理npm源nrm(npm registry manager)是npm的镜像管理工具,有时候国外的资源太慢,应用这个就能够疾速地在npm源间切换。 3.1 命令行窗口输出npm install -g nrm即可装置nrm 3.2 命令行窗口输出nrm -V 大写的v, 能够看到版本号即可装置胜利 3.3 命令行窗口输出nrm ls 查看可选源,或者应用nrm current查看以后正在应用的npm源 3.4 命令行窗口输出nrm use taobao 就是切换到淘宝源 3.5 当你公司或集体有本人的npm源则能够通过命令nrm add <key> <url> key: 键,起个名字, url: 值,公有npm地址 3.6 能减少就能删除nrm del <key> key:想要删除的源名称 3.7 测试一下你源链接速度 nrm test <key> 即可看到key源的响应工夫npm其余配置咋办?4.1 我的项目配置文件:你能够在我的项目的根目录下创立一个.npmrc文件,只用于治理这个我的项目的npm装置。输出: registry=https://registry.npm.taobao.org 则在这个我的项目内执行npm命令操作时候就会读取这个配置作用与以后我的项目 4.2 用户配置文件:在你应用一个账号登陆的电脑的时候,能够为以后用户创立一个.npmrc文件,之后用该用户登录电脑,就能够应用该配置文件。能够通过 npm config get userconfig 来获取该文件的地位。 4.3 全局配置文件: 一台电脑可能有多个用户,在这些用户之上,你能够设置一个公共的npmrc文件,供所有用户应用。该文件的门路为:$PREFIX/etc/npmrc,应用 npm config get prefix 获取 ...

May 14, 2023 · 1 min · jiezi

关于webpack:Webpack5源码enhancedresolve路径解析库源码分析

本文内容基于webpack 5.74.0和enhanced-resolve 5.12.0版本进行剖析 因为enhanced-resolve兼容了多种简单状况的解析,想要将这些状况进行详细分析太消耗精力,因而本文只是尝试将所有流程进行通俗剖析,通过本文,你能够对webpack的resolve配置有一个整体的理解,如果对这方面想更加深刻地钻研,请联合其它文章进行浏览 本文是「Webpack5源码」make阶段(流程图)剖析的补充文章,如果对webpack流程不相熟,请先看「Webpack5源码」make阶段(流程图)剖析 文章内容简要介绍webpack是如何应用enhanced-resolve进行门路解析分为三个流程图展现enhanced-resolve的解析流程,并为每一个流程图简略形容整体流程整体流程剖析从上图能够晓得,咱们在webpack解析过程中,会初始化this.getResolve("loader")和this.getResolve("normal") resolve一共分为两种配置,一种是文件类型的门路解析配置,一种是 loader 包的解析配置,比方上图中的内联url解析进去的到"babel-loader"和"./index_item-line","babel-loader"会应用getResolve("loader")进行解析,"./index_item-line"会应用getResolve("normal")进行解析 必须是内联url才会触发resolveRequestArray()和defaultResolve()?是的,从源码上看只有解析到"-!"、"!"、!!"才会使得unresolvedResource和elements两个数据不为空,才会触发resolveRequestArray()和defaultResolve() 如果是import _ from "loadsh"会不会触发getResolve("loader")进行解析?答案是不会的 typenormalloaderresolveOptions其中normal的参数获取是合并了webpack.config.js和默认options的后果入口文件是EntryDependency,它具备默认的category="esm" class EntryDependency extends ModuleDependency { /** * @param {string} request request path for entry */ constructor(request) { super(request); } get type() { return "entry"; } get category() { return "esm"; }}而在初始化normal类型的Resolver时,会触发hooks.resolveOptions进行webpack.config.js和一些默认参数的初始化 // node_modules/webpack/lib/ResolverFactory.js_create(type, resolveOptionsWithDepType) { /** @type {ResolveOptionsWithDependencyType} */ const originalResolveOptions = { ...resolveOptionsWithDepType }; const resolveOptionsTemp = this.hooks.resolveOptions.for(type).call(resolveOptionsWithDepType); const resolveOptions = convertToResolveOptions( resolveOptionsTemp );}// node_modules/webpack/lib/WebpackOptionsApply.jscompiler.resolverFactory.hooks.resolveOptions .for("normal") .tap("WebpackOptionsApply", resolveOptions => { resolveOptions = cleverMerge(options.resolve, resolveOptions); resolveOptions.fileSystem = compiler.inputFileSystem; return resolveOptions; });this.hooks.resolveOptions.for(type).call(resolveOptionsWithDepType)获取到的数据如下图所示 ...

May 7, 2023 · 7 min · jiezi

关于webpack:Webpack5源码make阶段流程图分析

本文内容基于webpack 5.74.0版本进行剖析 因为webpack5整体代码过于简单,为了缩小复杂度,本文所有剖析将只基于js文件类型进行剖析,不会对其它类型(css、image)进行剖析,所举的例子也都是基于js类型 为了减少可读性,会对源码进行删减、调整程序、扭转的操作,文中所有源码均可视作为伪代码,并且文章默认读者曾经把握tapable、loader、plugin等基础知识,对文章中呈现asyncQueue、tapable、loader、plugin相干代码都会间接展现,不会减少过多阐明 文章内容从npm run build命令开始,剖析webpack入口文件的源码执行流程,剖析是如何执行到make阶段和seal阶段剖析make阶段的factorizeModule()的执行流程剖析make阶段的buildMode()的执行流程剖析make阶段的processModuleDependencies()的执行流程1. 初始化1.1 npm run build1.1.1 源码剖析当咱们执行npm run build的时候,理论就是执行bin/webpack.js { "scripts": { "build-debugger": "node --inspect-brk ./node_modules/webpack/bin/webpack.js --config webpack.config.js --progress", "build": "webpack" }}在bin/webpack.js,最终会加载webpack-cli/package.json的bin字段,也就是./bin/cli.js const cli = { name: "webpack-cli", package: "webpack-cli", binName: "webpack-cli", installed: isInstalled("webpack-cli"), url: "https://github.com/webpack/webpack-cli"};const runCli = cli => { const path = require("path"); const pkgPath = require.resolve(`${cli.package}/package.json`); // eslint-disable-next-line node/no-missing-require const pkg = require(pkgPath); // eslint-disable-next-line node/no-missing-require require(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName]));};runCli(cli);// webpack-cli/package.json"bin": { "webpack-cli": "./bin/cli.js"}在webpack-cli/bin/cli.js中,触发了new WebpackCLI()和run()办法 ...

May 7, 2023 · 17 min · jiezi

关于webpack:Webpack5-入门与实战前端开发必备技能聊自整云装

download:Webpack5 入门与实战,前端开发必备技能全局视角零碎:让你的业务更加通明高效 随着信息化技术的一直倒退,越来越多的企业开始关注如何晋升本身的经营效率和管理水平。在这个过程中,全局视角零碎成为了一个备受关注的工具。那么什么是全局视角零碎呢?它又能为企业带来怎么的价值呢? 简略来说,全局视角零碎就是一种能够将企业各个部门和业务的数据进行整合、剖析和展现的工具。通过这个零碎,企业能够在一个对立的平台上理解到公司外部各个部门的经营情况、各项业务的停顿状况以及市场的变化趋势等信息。这些信息能够通过报表、图表、数据可视化等形式进行出现,让企业管理者可能更加直观地理解公司的经营情况。 那么全局视角零碎又有哪些劣势呢?首先,它可能让企业的各个部门之间实现信息共享和协同工作。在传统的企业治理中,不同部门之间往往存在信息孤岛,导致信息无奈共享,协同工作效率低下。而全局视角零碎正是通过整合各个部门的数据,买通信息壁垒,让企业外部实现更加高效的协同工作。 其次,全局视角零碎可能帮忙企业管理者及时发现问题并进行修改。在过来,企业管理者往往须要通过手动收集各种报表和数据来理解公司的经营状况,这样不仅费时费力,而且容易疏忽一些重要的信息。而全局视角零碎则能够将各类数据主动整合,造成全面的经营报告,让管理者可能及时发现问题,并采取相应的措施进行解决。 最初,全局视角零碎还可能为企业的决策提供无效的反对。通过对各个部门和业务的数据进行综合剖析,全局视角零碎能够帮忙企业管理者做出更加迷信的决策。比方,在市场竞争强烈的行业中,全局视角零碎能够帮忙企业理解竞争对手的动静,从而制订出更加优良的策略。 总之,全局视角零碎是一个十分有价值的工具,它可能帮忙企业管理者更好地理解公司的经营情况,及时发现问题并进行修改,为企业的决策提供无效的反对。因而,如果您的企业还没有应用全局视角零碎,那么当初就是引入的好时机了!

May 3, 2023 · 1 min · jiezi

关于webpack:webpack从一个简化后的webpac异步加载打包代码了解webpack异步加载原理

前言 本文剖析webpack5的异步加载原理,代码是简化后的,原代码大略200行,简化后100行左右,然而性能仍旧能够失常实现。 注释首先贴出所有的代码,而后剖析。这是未打包的代码: index.js代码,引入了test.js,然而是通过import异步引入。 // index.jsimport("./test").then(val => { console.log(val)})test.js, 默认导出了一个字符串。 // test.jsexport default "test代码"这是打包后的代码。 // index.js打包代码var webpackModules = {};var webpackModuleCache = {};function webpackRequire(moduleId) { var cachedModule = webpackModuleCache[moduleId]; if (cachedModule !== undefined) { return cachedModule.exports; } var module = webpackModuleCache[moduleId] = { exports: {} }; webpackModules[moduleId](module, module.exports, webpackRequire); return module.exports;}webpackRequire.m = webpackModules;(() => { webpackRequire.d = (exports, definition) => { for (var key in definition) { if (webpackRequire.o(definition, key) && !webpackRequire.o(exports, key)) { Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); } } };})();(() => { webpackRequire.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);})();(() => { webpackRequire.r = exports => { if (typeof Symbol !== 'undefined' && Symbol.toStringTag) { Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); } Object.defineProperty(exports, 'esmodule', { value: true }); };})();var webpackJsonpCallback = ([chunkIds, moreModules]) => { var resolves = [] for (var i = 0; i < chunkIds.length; i++) { var resolve = installedChunks[chunkIds[i]][0] resolves.push(resolve) // 0示意加载结束 installedChunks[chunkIds[i]] = 0 } for (var key in moreModules) { webpackRequire.m[key] = moreModules[key]; } // 模块加载结束,执行resolve。 while (resolves.length > 0) { resolves.shift()() }}webpackRequire.f = {}var installedChunks = { main: 0}webpackRequire.p = "";webpackRequire.u = (chunkId) => chunkId + ".js";// 3webpackRequire.l = (url) => { var script = document.createElement("script"); script.src = url; document.head.appendChild(script);}// 2webpackRequire.f.j = (chunkId, promises) => { var installedChunkData = installedChunks[chunkId]; // 阐明这个chunk曾经加载过了 if (installedChunkData !== undefined) { return } var promise = new Promise((resolve, reject) => { installedChunkData = installedChunks[chunkId] = [resolve, reject]; }) installedChunkData[2] = promise; promises.push(promise); var url = webpackRequire.p + webpackRequire.u(chunkId); webpackRequire.l(url)}// 1webpackRequire.e = (chunkId) => { var promises = []; webpackRequire.f.j(chunkId, promises); return Promise.all(promises)}// 4var wepackLoadingGlobal = window.webpackChunkwebpack2 = [];// 重写pushwepackLoadingGlobal.push = webpackJsonpCallbackwebpackRequire.e("src_test_js").then(webpackRequire.bind(webpackRequire, "./src/test.js")).then(val => { console.log(val);});这个是test.js打包后的代码 ...

April 17, 2023 · 3 min · jiezi

关于webpack:关于webpack的打包原理webpackJsonpCallback的学习笔记

援用自https://github.com/webpack/webpack/issues/10441,在这个webpack的issue中提到了webpackJsonpCallback的定义,上面是翻译。 代码中的webpackJsonpCallback是什么意思?webpackJsonpCallback是webpack在浏览器端异步加载模块的时候定义的全局函数。当webpack加载一个异步模块时,会生成一个script标签,指向异步模块的url,此时浏览器会异步加载这个js文件。在js文件中,会有一个webpackJsonpCallback函数被调用,它会把该异步模块的代码退出到以后网页的js代码中去。这就是webpack实现异步模块加载的形式之一。(原文) 具体学习:https://www.freecodecamp.org/chinese/news/webpack-module-load...

April 16, 2023 · 1 min · jiezi

关于webpack:从零配置一个前端开发环境webpack优化

前端开发开发环境系列文章的 github 在这,如果您在看的过程中发现了什么有余和谬误,感谢您能指出! 作为一个前端开发,Webpack肯定不生疏,在前端这一畛域,大多数的我的项目应该都是用webpack作为一个模块打包工具。然而当我的项目的规模变大后,应该都或多或少的遇到了性能相干的问题。 而以webpack作为工具,则能够将性能分为两种: 构建速度页面加载速度以这两个为目标,对咱们的我的项目进行优化。 尽量应用高版本的webpack和nodeWebpack和Node每次一大版本的更新都会随同着性能优化,这是最间接显著的 speed-measure-webpack-plugin该插件的作用就是剖析loader和plugin的打包速度,针对信息定制优化计划 装置yarn add speed-measure-webpack-plugin -D webpack.config.js const SpeedMeasureWebpackPlugin = require('speed-measure-webpack-plugin')const swp = new SpeedMeasureWebpackPlugin()module.exports = swp.wrap(yourConfig);webpack-bundle-analyzer剖析打包模块体积 多线程进行TypeScript的类型查看在我的项目中应用了ts-loader后,我的项目中ts文件的类型查看会十分的耗时。所以咱们通过ts-loader的配置敞开类型查看,并是应用fork-ts-checker-webpack-plugin在别的线程查看。这会大大减少webpack的编译工夫。 yarn add fork-ts-checker-webpack-plugin -D module.exports = { module: { rules: [ { test: /\.ts(x)?$/, use: [ { loader: 'ts-loader', options: { // 敞开类型查看,即只进行转译 // 类型查看交给 fork-ts-checker-webpack-plugin 在别的的线程中做 transpileOnly: true, }, }, ], exclude: /node_modules/, }, ] }, plugins: [ new ForkTsCheckerWebpackPlugin(), ]}预编译资源模块(该计划在webpack4之后,优化成果就不是很显著了)应用webpack官网的DllPlugin进行分包 思路: 将一些根底且比较稳定的包打包成一个文件,如react、react-dom、redux、react-redux办法: DLLPlugin分包,DllReferencePlugin对manifest.json援用。援用manifest.json会主动关联DllPulugin中的包这须要一个独自的 webpack.dll.js 配置文件 const path = require('path');const webpack = require('webpack');module.exports = { mode: 'development', resolve: { extensions: ['.js', '.jsx', '.json', '.less', '.css'], modules: [__dirname, 'node_modules'] }, entry: { // 制订须要拆散的包 react: ['react', 'react-dom', 'redux', 'react-redux'], }, output: { filename: '[name].dll.js', path: path.join(__dirname, 'dll/'), library: '[name]_[fullhash]', }, plugins: [ new webpack.DllPlugin({ name: '[name]_[fullhash]', path: path.join(__dirname, 'dll', 'manifest.json'), }), ],};在根目录创立一个dll目录,而后运行webpack --config webpack.dll.js,将一些根底包提前编译进去,dll目录下会有 manifest.json react.dll.js两个文件 ...

March 11, 2023 · 2 min · jiezi

关于webpack:回顾webpack在vueconfigjs中写loader和plugin

前言咱们先思考一个问题:如果不应用webpack,前端可能开发我的项目吗? 先别着急说出答案,咱们持续往下看... 工作中,咱们都是应用框架的脚手架进行开发,支流的趋势...vue-cli & create-react-app和webpack的关系咱们晓得,无论是Vue的vue-cli还是React的create-react-app这样的脚手架,实际上都是给webpack做了一层封装,包了一层壳子,并预设了一些默认罕用的配置项(当然还有别的货色),以便晋升开发效率。 所以它们的关系是:脚手架只是给webpack穿上了一个马甲...不过有时候脚手架提供的默认配置项不够用了,就须要咱们手动去写一些plugin或者loader从而实现咱们想要的性能。 学习本文的播种通俗易懂地回顾webpack知识点学习在vue-cli脚手架中写webpack的plugin的知识点学习在vue-cli脚手架中写webpack的loader的知识点webpack平时咱们写代码都是模块化、组件化(工程化)进行开发,导致代码会进行拆分、细化、公共局部提取、援用等...为何要模块化、组件化(工程化)进行开发呢?因为:这是软件开发的支流和趋势... 什么是webpack & 谈谈你对webpack的了解平时咱们写代码都是模块化、组件化(工程化)进行开发,导致代码会进行拆分、细化、公共局部提取、援用等...比方:咱们会写很多.vue文件(当然还有别的文件如.less等)。然而咱们写的代码是最终要被浏览器拜访解析执行的,而浏览器不意识.vue文件,也不意识.less文件!浏览器不意识就不能解析,不能用。浏览器倒是意识js、css、html,能够解析出相应内容,并渲染展现。又因为 .vue文件和.less文件实际上也只是html、css、js化妆之后的款式。那这样,搞一个工具,可能让.vue文件和.less文件卸妆成html、css、js就行了。而webpack恰好可能做到这一点(编译转化打包)所以,webpack就是:一个转化编译打包工具,将一些浏览器不意识的花里胡哨的文件转化为浏览器意识的html、css、js文件。 还记得咱们最终打包好的dist文件夹目录吗?外面就只有:html、css、js等一些资源... 这样形容,不是非常谨严。精确来说,webpack是一个动态模块资源打包工具,官网:https://webpack.docschina.org/concepts/ 回到最开始的那个问题~ 如果不应用webpack,前端可能开发我的项目吗?问:如果不应用webpack,前端可能开发我的项目吗?答:如果一个我的项目炒鸡小,只是用来展现一点点货色,齐全能够应用原生的html、css、js去写,这样的话,就用不到咱们要晓得webpack的作用就是,去转化编译打包脚手架、工程化的大我的项目。如果是一个小我的项目,齐全不须要去用工程化的形式开发,间接写,写完了丢到服务器上,间接用 前端工程化 == 模块化 + 组件化 + 自动化 + ...webpack的几个重要概念打包入口(entry)打包输入(output)加载器(loader)插件(plugin)模式(mode)nodejs环境(environment)webpack打包入口-entry咱们晓得,咱们开发我的项目有很多文件,比方a、b、c等。a援用了b中的货色,而b又援用了c中的货色。那么打包翻译的话,就须要指定从哪个文件开始打包,打包的过程中如果遇到了有别的援用,就顺藤摸瓜...webpack中默认打包的入口文件是./src/index.js文件,这个文件中援用了好多别的文件,所以webpack持续顺藤摸瓜寻找、编译、转化、打包。而vue-cli脚手架中的入口文件是src目录下的main.js文件(vue-cli改写了webpack默认的入口文件地位罢了)这里咱们能够去vue-cli仓库代码中去找到相干的代码,能看到指定的打包入口vue-cli仓库地址:https://github.com/vuejs/vue-cli 大家把代码下载下来,Code --> Download ZIP ,而后在vscode中关上代码,在左上角第二个放大镜中搜寻关键字:src/main.js 有很多的关键词,其中有一个get entryFile办法,代码如下: /*** Get the entry file taking into account typescript.** @readonly*/get entryFile () { if (this._entryFile) return this._entryFile return (this._entryFile = fs.existsSync(this.resolve('src/main.ts')) ? 'src/main.ts' : 'src/main.js')}对应截图如下: 其实vue-cli中有很多的中央的代码,都告知了咱们vue-cli是将main.js作为webpack打包的入口的,大家多看看...好了,至此咱们见证了webpack的打包入口(entry)在vue-cli脚手架中的具体利用展示模式。大家也能够在create-react-app中去看一下webpack的打包入口文件,一个意思 vue-cli和webpack的关系,换句话说,也像苹果手机和富士康的关系...webpack打包输入-output咱们晓得,平时我的项目写完,公布上线,打包输入的个别都是一个dist文件夹(也能够改) 原始的webpack是这样写: const path = require('path');module.exports = { entry: './src/index.js', // 从以后同级目录下的index.js作为入口文件,顺藤摸瓜开始打包 output: { path: path.resolve(__dirname, 'dist'), // 这里的path值要是一个绝对路径,如:E:\echarts\code\dist,所以要应用path模块来操作 filename: 'myDemo.js', },};vue-cli中叫做outputDir并指定了默认值为dist(实际上就是webpack中的output,又是套壳子),咱们通过在vue.config.js文件中更改outputDir的值,即可批改打包换名字了 ...

March 10, 2023 · 8 min · jiezi

关于webpack:webpack4react18构建项目

1.开发环境 react18+webpack42.电脑系统 windows11专业版3.随着工作教训的积攒,咱们会发现官网脚手架创立进去的我的项目有很多都是没有用的,那咱们怎么本人从0开始创立我的项目呢?下来我来分享一下我的办法,心愿对你有所帮忙。4.在这里我抉择的是react,那么首先咱们须要先简略的来理解一下react。 开发React必须依赖三个库:react:蕴含react所必须的外围代码react-dom:react渲染在不同平台所须要的外围代码babel:将jsx转换成React代码的工具4-1. react 依赖外围: react : react 包中蕴含了react和react-native所共有的外围代码。react-dom:react-dom针对web和native所实现的事件不同:web端:react-dom会讲jsx最终渲染成实在的DOM,显示在浏览器中native端:react-dom会讲jsx最终渲染成原生的控件(比方Android中的Button,iOS中的UIButton)。babel:比方当下很多浏览器并不反对ES6的语法,然而的确ES6的语法十分的简洁和不便,咱们开发时心愿应用它。那么编写源码时咱们就能够应用ES6来编写,之后通过Babel工具,将ES6转成大多数浏览器都反对的ES5的语法。5.初始化我的项目: npm init -y6.首先是装置: // react 装置npm i react react-dom -Sor npm i react@18 react-dom@18 -S// babel依赖装置,具体能够看babel 官网npm i @babel/preset-env @babel/preset-react @babel/core babel-loader@8 -D// webpack 装置npm webpack@4 webpack-cli@4 webpack-dev-server html-webpack-plugin@4 -D7.创立src目录,在src目录创立index.js和index.html // index.jsimport React from 'react';// 留神这里ReactDOM是从client引入import ReactDOM from 'react-dom/client';function App () { return (<div>Hello,Chen</div>)}ReactDOM.createRoot(document.getElementById('app')).render(<App />);// index.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>chen-react-admin</title></head><body><div id="app"></div></body></html>8.创立webpack.config.js(和package.json同级) const path = require("path");const htmlWebpackPlugin = require('html-webpack-plugin');module.exports = { entry:'./src/index.js', output: { filename: 'index.js',//进口文件名 path: path.resolve(__dirname, 'dist'),//进口门路 }, mode: 'development',//模式 module:{ rules:[ { test:/\.(js|jsx)$/, use:{ loader:'babel-loader' } } ] }, plugins:[ new htmlWebpackPlugin({ template:'./src/index.html' }) ]}9.创立babel.config.js(和package.json同级) ...

February 28, 2023 · 1 min · jiezi

关于webpack:cssProcessorprocesscsssource-processOptions-报错css压缩之性能优化

问题形容应用optimize-css-assets-webpack-plugin和cssnano插件在vue我的项目中进行css压缩。在npm run build打包时报错了报错截图如下: 问题起因-插件版本问题笔者的我的项目的webpack版本是4版本,下载的用于压缩我的项目中css的插件的版本别离是最新版的optimize-css-assets-webpack-plugin和cssnano。版本别离是: "devDependencies": { ... "optimize-css-assets-webpack-plugin": "^6.0.1", "cssnano": "^5.1.14", ... },间接cnpm i xxx 就会默认下载最新的xxx包,最好指定版本笔者尝试了一下,只须要将版本升高一下就行了,下图是笔者应用的对应版本 cnpm install --save-dev optimize-css-assets-webpack-plugin@5.0.8cnpm install cssnano@4.1.11 -D 也就是npm上的下载人数最多的版本(稳定版),如下图: 大家当前遇到webpack的相干插件报错时,能够思考是不是插件版本的问题。最新版的插件和之前版本的插件相比,可能一些语法,或者写法产生了变动,导致插件在执行时报错。所以在装置插件时最好去npm上看看哪个版本的下载次数最多,下载次数最多的那个版本,也是最稳定版。当然也要看看相应版本的公布工夫,综合比拟抉择css压缩步骤在我的项目优化时,各种资源,视状况而定去压缩如图片压缩、字体压缩、js压缩、当然css能压缩,也去压缩一下下顺带记录一下vue我的项目中应用optimize-css-assets-webpack-plugin和cssnano插件压缩流程以及压缩前后的比照第一步,下载插件包下载指定版本的插件包(webpack4版本) // 淘宝镜像cnpm install --save-dev optimize-css-assets-webpack-plugin@5.0.8cnpm install cssnano@4.1.11 -D 第二步,在vue.config.js中的configureWebpack中应用咱们晓得configureWebpack有对象和函数两种写法,两种写法举例如下: 对象写法 // 引入两个插件包const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')const cssnano = require('cssnano')module.exports = { configureWebpack: { plugins: [ new OptimizeCSSAssetsPlugin({ // 实例化一个此插件 assetNameRegExp: /\.(sa|sc|c)ss$/g, // 通过正则匹配要去履行压缩的款式文件 cssProcessor: cssnano, // 依赖于cssnano进行压缩计算 cssProcessorPluginOptions: { // 配置项 preset: ['default', { safe: true, //设置为平安,防止cssnano从新计算 discardComments: { removeAll: true }, //把正文都革除掉 normalizeUnicode: false // 倡议false,否则在应用unicode-range的时候会产生乱码 }] }, }), ] },}函数写法 ...

January 17, 2023 · 1 min · jiezi

关于webpack:background-urlobject-Module背景图无法加载urlloader压缩图片配置问题

问题形容在vue.config.js文件中应用url-loader压缩图片当前,启动我的项目,发现背景图加载不进去了,F12审查dom发现背景图的的url变成对象模块了,如下图: 问题剖析url-loader应用的是ES的模块化语法,就是import 'xxx';如下官网文档截图: 可是vue在被编译后,应用的是CommonJS模块化语法,就是require('xxx')。二者有抵触,不统一,就会导致无奈读取图片文件了。 解决方案既然是vue我的项目,就让url-loader的配置与vue保持一致即可,所以敞开esModule,应用vue的规定即可。既然esModule选项默认为true,那么改为false就行了(敞开了es模块化语法)`^_^ 代码如下chainWebpack(config) { // ...... config.module.rule("images").test(/\.(jpg|jpeg|png|gif|ico)$/) .use("url-loader") .loader("url-loader") .options({ limit: 1024 * 12, name: "static/img/[name].[ext]", esModule: false // 这里,置为false即可 })}A good memory is better than a bad pen. Write it down

January 8, 2023 · 1 min · jiezi

关于webpack:教你开发webpack插件tozipwebpackplugin

to-zip-webpack-plugin 插件是一个webpack 打包产物(output目录)的压缩插件。对于常常对打包目录进行压缩的同学来说,省掉了手动压缩的步骤。本文将教你本插件的根本用法以及插件的具体实现。插件目前已放到github上,同时也公布到了npmgithub地址:https://github.com/booms21/to... 插件的根本应用首先咱们建设一个简略的React + Webpack的我的项目xxbot,而后在webpack.config.js退出 new ToZipWebpackPlugin() 这里不必退出任何配置,因为默认会去压缩build后的dist文件(output)。咱们运行npm run build 命令,看到build实现后多了一个...3823.zip的压缩文件,关上这个文件,发现和打包后的产物dist文件夹一样。 当然也能够退出一些配置使压缩操作更加定制化: 比方如下配置,把dist压缩成工夫戳.tar文件,并且额定压缩一个README.md文件,压缩到当前目录。 解压...7229.tar 和mymd.tar,发现这两个文件内容没有问题。两个不同的压缩工作是互不影响的,当须要产出压缩文件此时就能够拿去用了,当然还有其余配置。 插件外部的实现上面咱们看一下这个插件的具体实现:首先咱们查看webpack的官网对插件的阐明: 官网文档说是在plugin属性种传入的是一个插件的实例,而且也须要含有一个apply办法。所以咱们须要应用class的形式实现: 咱们的插件次要的工作是压缩webpack output的产出文件,所以咱们要在官网的插件列表中找到一个afterEmit钩子来实现插件的性能(当文件输入到output目录之后进行压缩)在入口文件index.js中创立一个ToZipWebpackPlugin类,并在构造函数中对所有参数设置默认值:index.js class ToZipWebpackPlugin { constructor({ zlibLevel, format, fileName, defaultFileName, source, log, deleteFileList, archive, } = {}) { const FILETYPE = ["zip", "tar"]; //反对的压缩文件类型 this.options = {}; this.timeFormatter = new TimeFormatter(); this.options.zlibLevel = isNaN(zlibLevel) ? 9 : zlibLevel; //默认压缩等级为9 this.options.format = FILETYPE.includes(format) ? format : "zip"; //默认类型为zip this.options.fileName = isString(fileName) ? fileName : this.getFileName("time"); //默认文件名为工夫字符串 isString(defaultFileName) ? (this.options.fileName = this.getFileName(defaultFileName) || this.options.fileName) : this.options.fileName; this.options.source = isString(source) ? source : ""; this.options.deleteFileList = deleteFileList; this.options.archive = archive; this.options.log = log; } delete(deleteFileList) { return del(deleteFileList); } getFileName(type) { const typeTable = { timestamp: String(this.timeFormatter.getTimestamp()), time: this.timeFormatter.getDateStr("yyyymmddhhMMss"), uuid: v4(), }; return typeTable[type]; } apply(compiler) { compiler.hooks.afterEmit.tapAsync( "ToZipWebpackPlugin", (complition, callback) => { this.options.archive && doArchive(this.options); //压缩前的压缩操作 outputArchive(this.options, complition.options.output.path); isArray(this.options.deleteFileList) && this.delete(this.options.deleteFileList); callback(); } ); }}在钩子回调中退出3个步骤:压缩前执行的自定义压缩archive > 默认的output压缩 > 最初的删除文件记得最初须要执行callback(); ...

December 25, 2022 · 3 min · jiezi

关于webpack:深度解读Webpack中的loader原理

一、前言webpack 是一个古代 JavaScript 利用的动态模块打包器。那么 webpack 是怎么实现不同品种资源模块加载的呢? 没错就是通过 loader。loader 用于对模块的源代码进行转换。loader 能够使你在 import 或加载模块时预处理文件。 咱们带着上面几个问题,彻底吃透 loader ~ 二、为什么要应用 loaderwebpack 是如何加载资源模块的呢?咱们先试着用 webpack 间接打包我的项目中的 css 文件。 初始化一个 webpack 我的项目,目录如下: 在 src 目录下新建了一个 index.css 文件,这里新建这个文件的目标就是以 css 文件为入口,尝试应用 webpack 独自打包它。 /* index.css */body { margin: 0 auto; padding: 0 20px; width: 1000px; background-color: #ccc;}调整下 webpack 配置,让入口文件门路指定为 index.css 的门路。 // webpack.config.jsmodule.exports = { entry: "./src/index.css", output: { filename: "bundle.js", },};而后咱们到终端运行 npx webpack 命令,你会发现命令行会提醒 Module parse failed: Unexpected token (1:5) 模块解析谬误。 ...

November 18, 2022 · 3 min · jiezi

关于webpack:详解webpack构建优化

当我的项目越来越简单时,会面临着构建速度慢和构建进去的文件体积大的问题。webapck构建优化对于大我的项目是必须要思考的一件事,上面咱们就从速度和体积两方面来探讨构建优化的策略。 剖析工具在优化之前,咱们须要理解一些量化剖析的工具,应用它们来帮忙咱们剖析须要优化的点。 webpackbarwebpackbar能够在打包时实时显示打包进度。配置也很简略,在plugins数组中退出即可: const WebpackBar = require('webpackbar')module.exports = { plugins: [ ... new WebpackBar() ]}speed-measure-webpack-plugin应用speed-measure-webpack-plugin能够看到每个loader和plugin的耗时状况。 和一般插件的应用略有不同,须要用它的wrap办法包裹整个webpack配置项。 const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')const smp = new SpeedMeasurePlugin()module.exports = smp.wrap({ entry: './src/main.js', ...})打包后,在命令行的输入信息如下,咱们能够看出哪些loader和plugin耗时比拟久,而后对其进行优化。 webpack-bundle-analyzerwebpack-bundle-analyzer以可视化的形式让咱们直观地看到打包的bundle中到底蕴含哪些模块内容,以及每一个模块的体积大小。咱们能够依据这些信息去剖析我的项目构造,调整打包配置,进行优化。 在plugins数组中退出该插件。构建实现后,默认会在http://127.0.0.1:8888/展现剖析后果。 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPluginmodule.exports = { plugins: [ ... new BundleAnalyzerPlugin() ]} webpack-bundle-analyzer会计算出模块文件在三种情景下的大小: stat:文件未通过任何转换的原始大小parsed:文件通过转换后的输入大小(比方babel-loader转换ES6->ES5、UglifyJsPlugin压缩等等)gzip:parsed后的文件,通过Gzip压缩的大小应用speed-measure-webpack-plugin和webpack-bundle-analyzer自身也会减少打包工夫(webpack-bundle-analyzer特地耗时),所以倡议这两个插件在开发剖析时应用,而在生产环境去掉。 优化构建速度多过程构建运行在Node.js之上的 Webpack 是单线程的,就算有多个工作同时存在,它们也只能一个一个排队执行。当我的项目比较复杂时,构建就会比较慢。现在大多数CPU都是多核的,咱们能够借助一些工具,充沛开释 CPU 在多核并发方面的劣势。 比拟常见的有happypack、thread-loader。 happypackhappypack可能将构建工作合成给多个子过程去并发执行,子过程解决完后再把后果发送给主过程。应用配置如下,就是把原有的loader的配置转移到happyPack中去解决。 const Happypack = require('happypack')module.exports = { module:{ rules:[ { test: /\.js$/, use: 'happypack/loader?id=babel' //问号前面的查问参数指定了解决这类文件的HappyPack实例的名字 }, ] }, plugins:[ new Happypack({ id: 'babel', //HappyPack实例名,对应下面rules中的“id=babel” use: ['babel-loader'] //本来要应用的loader }) ]}thread-loaderhappypack的作者曾经没有这个我的项目进行保护了,在webpack4之后,能够应用thread-loader。 ...

November 18, 2022 · 2 min · jiezi

关于webpack:Webpack完整打包流程分析

前言webpack 在前端工程畛域起到了中流砥柱的作用,了解它的外部实现机制会对你的工程建设提供很大的帮忙(不论是定制性能还是优化打包)。 上面咱们基于 webpack5 源码构造,对整个打包流程进行简略梳理并进行实现,便与思考和了解每个阶段所做的事件,为今后扩大和定制工程化能力打下基础。 一、筹备工作在流程剖析过程中咱们会简略实现 webpack 的一些性能,局部性能的实现会借助第三方工具: tapable 提供 Hooks 机制来接入插件进行工作;babel 相干依赖可用于将源代码解析为 AST,进行模块依赖收集和代码改写。// 创立仓库mkdir webpack-demo && cd webpack-demo && npm init -y// 装置 babel 相干依赖npm install @babel/parser @babel/traverse @babel/types @babel/generator -D// 装置 tapable(注册/触发事件流)和 fs-extra 文件操作依赖npm install tapable fs-extra -D接下来咱们在 src 目录下新建两个入口文件和一个公共模块文件: mkdir src && cd src && touch entry1.js && touch entry2.js && touch module.js并别离为文件增加一些内容: // src/entry1.jsconst module = require('./module');const start = () => 'start';start();console.log('entry1 module: ', module);// src/entry2.jsconst module = require('./module');const end = () => 'end';end();console.log('entry2 module: ', module);// src/module.jsconst name = 'cegz';module.exports = { name,};有了打包入口,咱们再来创立一个 webpack.config.js 配置文件做一些根底配置: ...

November 8, 2022 · 9 min · jiezi

关于webpack:Webpack插件核心原理

引言围绕 Webpack 打包流程中最外围的机制就是所谓的 Plugin 机制。 所谓插件即是 webpack 生态中最要害的局部, 它为社区用户提供了一种强有力的形式来间接涉及 webpack 的编译过程(compilation process)。 明天,咱们来聊聊 Webpack 中必不可少的外围 Plugin 机制 ~ Plugin实质上在 Webpack 编译阶段会为各个编译对象初始化不同的 Hook ,开发者能够在本人编写的 Plugin 中监听到这些 Hook ,在打包的某个特定时间段触发对应 Hook 注入特定的逻辑从而实现本人的行为。 对于 Plugin 中的 Hook 外部齐全是基于 tapable 来实现Plugin 中的罕用对象首先让咱们先来看看 Webpack 中哪些对象能够注册 Hook : compiler Hookcompilation HookContextModuleFactory HookJavascriptParser HooksNormalModuleFactory Hooks别放心,兴许对于这 5 个对象当初你会感觉到十分生疏,之后我会逐渐带你攻克它们。插件的根本形成咱们先来看这样一个最简略的插件,它会在 compilation(编译)实现时执行输入 done : class DonePlugin { apply(compiler) { // 调用 Compiler Hook 注册额定逻辑 compiler.hooks.done.tap('Plugin Done', () => { console.log('compilation done'); }); }}module.exports = DonePlugin;此时,在 compilation 实现时打包终端会打印进去一行 compilation done。 ...

November 8, 2022 · 3 min · jiezi

关于webpack:Webpack最佳实践

先简略回顾下 webpack 原理 Webpack 能够看做是模块打包机,把解析的所有模块变成一个对象,而后通过入口模块去加载咱们的货色,而后顺次实现递归的依赖关系,通过入口来运行所有的文件。因为 webpack 只意识js,所以须要通过一系列的 loader 和 plugin 转换成适合的格局供浏览器运行。 loader 次要是对资源进行加载/转译的预处理工作,其本质是一个函数,在该函数中对接管到的内容进行转换,返回转换后的后果。某种类型的资源能够应用多个 loader,执行程序是从右到左,从下到上。plugin(插件)次要是扩大 webpack 的性能,其本质是监听整个打包的生命周期。webpack 基于事件流框架 Tapable, 运行的生命周期中会播送出很多事件,plugin 能够监听这些事件,在适合的机会通过 webpack 提供的 API 扭转输入后果。webpack 装置新建一个目录,进入目录初始化 package.json,并装置 webpack 依赖 // 初始化包npm init -y// 装置依赖npm i webpack webpack-cli -D根底配置webpack 默认配置文件名字为 webpack.config.js,于是在我的项目根目录下新建一个名为 webpack.config.js 的文件,在配置文件里写最简略的单页面配置: let path = require("path");module.exports = { mode: "development", entry: "./src/js/index.js", output: { filename: "js/bundle.js", path: path.resolve("dist"), publicPath: "http://cdn.xxxxx" }}配置详解 mode - 打包模式 development 为开发模式,打包后代码不会被压缩production 为生产模式,打包后代码为压缩代码entry - 入口文件output - 打包文件配置 ...

November 8, 2022 · 7 min · jiezi

关于webpack:详解webpack构建优化

当我的项目越来越简单时,会面临着构建速度慢和构建进去的文件体积大的问题。webapck构建优化对于大我的项目是必须要思考的一件事,上面咱们就从速度和体积两方面来探讨构建优化的策略。 剖析工具在优化之前,咱们须要理解一些量化剖析的工具,应用它们来帮忙咱们剖析须要优化的点。 webpackbarwebpackbar能够在打包时实时显示打包进度。配置也很简略,在plugins数组中退出即可: const WebpackBar = require('webpackbar')module.exports = { plugins: [ ... new WebpackBar() ]}speed-measure-webpack-plugin应用speed-measure-webpack-plugin能够看到每个loader和plugin的耗时状况。 和一般插件的应用略有不同,须要用它的wrap办法包裹整个webpack配置项。 const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')const smp = new SpeedMeasurePlugin()module.exports = smp.wrap({ entry: './src/main.js', ...})打包后,在命令行的输入信息如下,咱们能够看出哪些loader和plugin耗时比拟久,而后对其进行优化。 webpack-bundle-analyzerwebpack-bundle-analyzer以可视化的形式让咱们直观地看到打包的bundle中到底蕴含哪些模块内容,以及每一个模块的体积大小。咱们能够依据这些信息去剖析我的项目构造,调整打包配置,进行优化。 在plugins数组中退出该插件。构建实现后,默认会在http://127.0.0.1:8888/展现剖析后果。 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPluginmodule.exports = { plugins: [ ... new BundleAnalyzerPlugin() ]} webpack-bundle-analyzer会计算出模块文件在三种情景下的大小: stat:文件未通过任何转换的原始大小parsed:文件通过转换后的输入大小(比方babel-loader转换ES6->ES5、UglifyJsPlugin压缩等等)gzip:parsed后的文件,通过Gzip压缩的大小应用speed-measure-webpack-plugin和webpack-bundle-analyzer自身也会减少打包工夫(webpack-bundle-analyzer特地耗时),所以倡议这两个插件在开发剖析时应用,而在生产环境去掉。 优化构建速度多过程构建运行在Node.js之上的 Webpack 是单线程的,就算有多个工作同时存在,它们也只能一个一个排队执行。当我的项目比较复杂时,构建就会比较慢。现在大多数CPU都是多核的,咱们能够借助一些工具,充沛开释 CPU 在多核并发方面的劣势。 比拟常见的有happypack、thread-loader。##### 参考webpack视频解说:进入学习 happypackhappypack可能将构建工作合成给多个子过程去并发执行,子过程解决完后再把后果发送给主过程。应用配置如下,就是把原有的loader的配置转移到happyPack中去解决。 const Happypack = require('happypack')module.exports = { module:{ rules:[ { test: /\.js$/, use: 'happypack/loader?id=babel' //问号前面的查问参数指定了解决这类文件的HappyPack实例的名字 }, ] }, plugins:[ new Happypack({ id: 'babel', //HappyPack实例名,对应下面rules中的“id=babel” use: ['babel-loader'] //本来要应用的loader }) ]}thread-loaderhappypack的作者曾经没有这个我的项目进行保护了,在webpack4之后,能够应用thread-loader。 ...

November 7, 2022 · 2 min · jiezi

关于webpack:Webpack中的plugin插件机制

大家有没有遇到过这些问题: webpack 打包之后的文件没有压缩动态文件要手动拷贝到输入目录代码中写了很多环境判断的多余代码上一篇 「webpack 外围个性」loader 说到 webpack 的 loader 机制,本文次要聊一聊另外一个外围个性:插件(plugin)。 插件机制就是为了实现我的项目中除了资源模块打包以外的其余自动化工作,解决上述的问题。 plugin 是用来扩大 webpack 性能的,通过在构建流程里注入钩子实现,它为 webpack 带来了很大的灵活性。 plugin 绝对于 loader 有哪些区别?loader 是转换器,将一种文件编译转换为另一个文件,操作的是文件。例如:将 .less 文件转换成 .css 文件。 plugin 是扩展器,它是针对 loader 完结之后,打包的整个过程。它并不间接操作文件,而是基于事件机制工作。在 webpack 构建流程中的特定时机会播送对应的事件,插件能够监听这些事件的产生,在特定的机会做对应的事件。包含:打包优化,资源管理,注入环境变量。 plugin 该怎么配置呢?例如 HtmlWebpackPlugin 能够为咱们生成一个 HTML 文件,其中包含应用 script 标签的 body 中的所有模块。看下如何配置: const HtmlWebpackPlugin = require('html-webpack-plugin');const webpackConfig = { ... plugins: [new HtmlWebpackPlugin()]};舒适提醒:loader 在 module.rules 中配置,作为模块的解析规定,类型为数组。每一项都是一个对象,外部蕴含了 test(类型文件)、loader、options(参数)等属性。plugin 则独自配置,类型为数组,每一项是一个 plugin 的实例,参数都通过构造函数传入。有哪些常见的 plugin?上面整顿的插件列表来自 webpack 中武官网,大家看见不相熟的 plugin 能够点击名称跳转,看一看,理解一下具体玩法。 名称形容AggressiveSplittingPlugin将原来的 chunk 分成更小的 chunkBabelMinifyWebpackPlugin应用 babel-minify进行压缩BannerPlugin在每个生成的 chunk 顶部增加 bannerCommonsChunkPlugin提取 chunks 之间共享的通用模块CompressionWebpackPlugin事后筹备的资源压缩版本,应用 Content-Encoding 提供拜访服务ContextReplacementPlugin重写 require 表达式的推断上下文CopyWebpackPlugin将单个文件或整个目录复制到构建目录DefinePlugin容许在编译时(compile time)配置的全局常量DllPlugin为了极大缩小构建工夫,进行 dll 分包EnvironmentPluginDefinePlugin 中 process.env 键的简写形式。ExtractTextWebpackPlugin从 bundle 中提取文本(CSS)到独自的文件HotModuleReplacementPlugin启用模块热替换(Enable Hot Module Replacement - HMR)HtmlWebpackPlugin简略创立 HTML 文件,用于服务器拜访I18nWebpackPlugin为 bundle 减少国际化反对IgnorePlugin从 bundle 中排除某些模块LimitChunkCountPlugin设置 chunk 的最小/最大限度,以微调和管制 chunkLoaderOptionsPlugin用于从 webpack 1 迁徙到 webpack 2MinChunkSizePlugin确保 chunk 大小超过指定限度NoEmitOnErrorsPlugin在输入阶段时,遇到编译谬误跳过NormalModuleReplacementPlugin替换与正则表达式匹配的资源NpmInstallWebpackPlugin在开发时主动装置短少的依赖ProvidePlugin不用通过 import/require 应用模块SourceMapDevToolPlugin对 source map 进行更细粒度的管制EvalSourceMapDevToolPlugin对 eval source map 进行更细粒度的管制UglifyjsWebpackPlugin能够管制我的项目中 UglifyJS 的版本ZopfliWebpackPlugin通过 node-zopfli 将资源事后压缩的版本怎么写一个 plugin?在说怎么写插件之前,先简略介绍几个好玩的货色:tapable、compiler 和 compilation。##### 参考webpack视频解说:进入学习 ...

November 7, 2022 · 3 min · jiezi

关于webpack:Webpack中的高级特性

自从webpack4当前,官网帮咱们集成了很多个性,比方在生产模式下代码压缩主动开启等,这篇文章咱们一起来探讨一下webpack给咱们提供的高级个性助力开发。 摸索webpack的高级个性个性:treeShaking顾名思义treeShaking,就是摇树,那么体现在代码模块外面就是摇掉那些没有被内部成员援用的代码,指的留神的是在生产环境下treeShaking会主动开启。 treeShaking初体验比方咱们在代码中引入lodash库,咱们只用到了once办法,那对于lodash其余的功能模块,在生产环境下打包,并不会输入到bundle.js文件外面,比方咱们在bundle.js外面去找lodash的一个办法debounce,他是齐全能够找失去的。 delelopment模式下打包的bundle.js production模式下打包的bundle.js 在这里你可能会说了production模式下会开启n多插件,解决打包后果,怎么就能阐明是treeShaking做的呢,的确这种做法不能阐明是treeShaking做的,咱们能够把mode设置为none再试一下,不过这里须要咱们手动去开启treeShaking,开启的形式如下。 // webpack.config.jsmodule.exports = { ... optimization: { usedExports: true, // 只导出内部成员援用模块 // 此属性用于模块导入合并,因为独自的模块导入要应用_webpack_require_函数。 // 此属性就是能够利用_webpack_require_一次性导入所有模块,也叫作用域晋升。 concatenateModules: true, minimize: true, // 开启代码压缩 } ...}none模式下打包的bundle.js所以none模式下,打包的后果仍然如此。 扩大因为treeShaking是依赖于ESM的,如果我的项目中有配合应用babel-loader那么treeShaking是不是会生效呢?咱们能够在配置文件外面增加babel-loader来辅以测试。 // 装置npm i babel-loader @babel/core @babel/preset-env -D// webpack.config.jsmodule.exports = { ... module:[ { test:/\.js$/, use:{ loader:'babel-loader', options:{ presets:[ ['@babel/preset-env'] ] } } } ]}文件成果咱们能够看到没有应用的代码,仍然是被移除掉了。 起因剖析因为babel-loader禁用了对ESM转化插件,所以通过babel-loader解决生成的仍旧是ESM代码,如果你想应用代码转换性能,那你就须要像上面这样配置,只不过这样treeShaking就会生效了。##### 参考webpack视频解说:进入学习 // 装置npm i babel-loader @babel/core @babel/preset-env -D// webpack.config.jsmodule.exports = { ... module:{ rules:[ { test:/\.js$/, use:{ loader:'babel-loader', options:{ presets:[ // 强制应用commonjs转换 ['@babel/preset-env', {modules: 'commonjs'}] ] } } } ] }}那么treeShaking生效了,应该怎么办?不要怕,即便生效了还会有其余插件提供了相似treeShaking性能,比方代码压缩。 ...

November 7, 2022 · 3 min · jiezi

关于webpack:手写一个webpack插件

前言前端性能优化是一个陈词滥调的话题,对于性能优化的技术文档和书籍都特地多。如果大家想深刻学习前端性能优化相干内容,有以下举荐 雅虎军规35条某东上搜“前端性能优化”,书籍也特地多。然而前端性能优化做的所有工作,都和一个灵魂拷问有极大的关系:在浏览器输出url后,产生了什么?首先url是一个域名,首先它要被解析成ip地址。如果你的设施之前拜访过该url,那么本地可能会缓存ip地址。如果没有缓存过,那么就向dns服务器进行解析。依据 IP 地址和默认端口建设TCP连贯,三次握手。浏览器收回HTTP申请;服务器对申请作出响应;此时兴许会有一些304之类的返回后果。会波及到http缓存机制。开释TCP连贯;浏览器将该html文本并显示内容。所以咱们能够从这个过程里去思考,服务器如何把文件尽快发送到客户浏览器。 第一点,就是文件尽可能要小,文件尽可能少,发送起来会更快第二点,就是发送过程,在肯定条件下,缩小文件或申请的个数。文件也并不是越少越好,假如文件内容少到极致,内容全副合并到一个文件,那么这个文件会是十分微小的,发送起来也会十分慢。如果文件个数太多,那么浏览器也会限度并发数量,在同一个域名下,浏览器的并发数量是6个。这样,尽管每个申请发送的文件很少,然而建设申请的过程也是耗时间的。很多申请都被阻塞了。以上是针对第一次拜访网站时可用的计划,然而如果一个网站常常被反复拜访,还有以下办法第三点,缓存机制 就是之前用到过的文件和内容,如果没有生效,就能够重复使用,不须要再从服务器拿。以上是我大略能想到的一些思路。如果有不精确的中央,或者有其余好的思路,心愿大家留言帮我补充。 上面咱们进入正题,说一下我在开发我的项目时遇到的一个问题,以及解决思路 开发过程遇到的一个理论问题在vue我的项目打包后,会在我的项目的根目录下生成一个dist(你也能够扭转该名称)文件夹。一个单页面利用的dist文件夹通常蕴含一个index.html 和 一个js文件夹 和一些其余资源文件。 而后咱们把dist文件夹公布到服务器上,在浏览器下来拜访咱们的我的项目,刚开始可能会特地慢。关上chrome调试工具,查看一下资源加载状况。 太惊人了,一个要害的js文件,在nginx服务器上曾经做了压缩解决,从800k压缩到270k左右。然而加载工夫仍然达到了惊人的22.89s。这个对于任何一个我的项目来说都是不可承受的。 初步解决思路问题曾经出现了。打包后的文件,呈现了特地大的js,而且就是这个js文件阻塞了整个我的项目的加载。因为最近正在钻研webpack相干内容。webpack大家应该都应用过。webpack是一个打包编译工具,它做的事件,就是把你开发的整个我的项目,编译成一个浏览器可间接辨认的我的项目。它蕴含以下一些根底概念: 1,入口文件入口文件,就是webpack工作的终点,从入口文件开始,咱们通常会import很多其余模块,import等模块化的开发方法,就把整个我的项目给串联起来了。依据这些依赖信息,webpack把整个我的项目解析为一个ast(形象语法树),这个树记录了所有的文件依赖门路。2,进口文件就是我的项目打包后寄存的目录,所有资源文件都会输入到这个文件夹3,loaderwebpack只能辨认es5的语法,对于es6等更新的语法,是不能辨认的,对于一些图片,css文件,jsx文件等各种不同后缀名的文件,都是须要loader进行解析的。loader做的事件也就是这些。4,plugin依据webpack官网文档,咱们晓得webpack在整个打包和编译的过程中,有几十个工夫节点。具体的内容能够看这个链接,在plugins目录下: webpack.docschina.org/api/compile…那么我做的一点小尝试,就是在文件打包并且输出到output文件夹后,找到要害的js文件(上图划红线的那个文件),上传到公司的阿里云oss。而后index.html文件本来是援用了output外面的js文件,改为援用oss外面的链接。这也是待会儿实现webpack自定义插件的次要思路。 最初的试验成果本来须要20多秒加载的文件,放到阿里云oss后,只须要0.5s的加载速度,是不是十分惊人呢。而后发现,影响页面加载的次要因素,曾经不是这个要害js了。咱们好能够在此基础根底上做其余优化。 插件代码 和 应用办法先看次要代码:在src目录下新建plugins文件夹,而后新建了一个UploadJsToCDNPlugin.js文件。这也是咱们的插件文件。##### 参考webpack视频解说:进入学习 src/plugins/UploadJsToCDNPlugin.js 文件内容如下: // const globby = require('globby');const path = require('path');const fs = require('fs');const axios = require('axios')var FormData = require('form-data')let replaceFile = function(filePath,sourceRegx,targetStr){ fs.readFile(filePath,function(err,data){ if(err){ return err; } let str = data.toString(); str = str.replace(sourceRegx,targetStr); fs.writeFile(filePath, str, function (err) { if (err) return err; }); });}class UploadJsToCDNPlugin { constructor(options = {}) { this.options = options; } apply(compiler) { console.log(compiler.options.mode) compiler.hooks.afterEmit.tap('UploadJsToCDNPlugin', async (params) => { try { const js_path = Object.keys(params.assets).find(item => item.includes('js/chunk-libs.'))// 请自行调整文件名称 const html_path = path.resolve(compiler.options.output.path, 'index.html') const file_path = path.resolve(compiler.options.output.path, js_path) // 因为是公司我的项目,已做脱敏解决,道歉 const url = 'https://wwwxxxxxx/file/upload' const form = FormData() form.append('file', fs.createReadStream(file_path), { filename: 'app.js' }) const res = await axios.create({ headers: form.getHeaders() }) .post(url,form) const cdn_path = res.data.data // 这行代码是本插件的外围代码 await replaceFile(html_path, /js\/chunk-libs.\w*.js/g, cdn_path)// 请自行调整文件名称 } catch (e) { e } }) }}module.exports = UploadJsToCDNPlugin;最初在vue.config.js外面应用webpack自定义webpack插件:vue.config.js 文件结尾: ...

November 4, 2022 · 1 min · jiezi

关于webpack:教你手写webpack常用loader

前言webpack 作为目前支流的前端构建工具,咱们简直每天都须要与它打交道。集体认为一个好的开源产品壮大的起因应该包含外围开发者的稳固输入以及对应生态的凋敝。对于生态来说, webpack 是一个足够凋谢的类库,提供了可插拔的形式去自定义一些配置,包含配置 loader 和 plugin ,本篇咱们次要探讨loader。 loader 实质上是一个函数,webpack在打包过程中会依照规定顺序调用解决某种文件的 loader ,而后将上一个 loader 产生的后果或者资源文件传入进去,以后 loader 解决实现后再交给下一个 loader 。 loader的类型开始之前,还是要先大略提一下 loader 的类型以及一些罕用的 api ,不感兴趣的同学能够间接跳过这一大节,更具体的指引请参阅官网文档。 loader 次要有以下几种类型: 同步 loader : return 或调用 this.callback 都是同步返回值异步 loader :是用 this.async() 获取异步函数,是用 this.callback() 返回值raw loader :默认状况下承受 utf-8 类型的字符串作为入参,若标记 raw 属性为 true ,则入参的类型为二进制数据pitch loader : loader 总是从右到左被调用。有些状况下,loader 只关怀 request 前面的 元数据(metadata),并且疏忽前一个 loader 的后果。在理论(从右到左)执行 loader 之前,会先从左到右调用 loader 上的 pitch 办法。开发 loader 时罕用的 API 如下: this.async :获取一个 callback 函数,解决异步this.callback :同步 loader 中,返回的办法this.emitFile :产生一个文件this.getOptions :依据传入的 schema 获取对应参数this.importModule :用于子编译器在构建时编译和执行申请this.resourcePath :以后资源文件的门路Hello Loader当初假如咱们有这么一个需要:在每个文件的头部打上开发者的相干信息。比方打包之前的文件内容是这样的: ...

November 4, 2022 · 7 min · jiezi

关于webpack:深度解读Webpack中的loader原理

一、前言webpack 是一个古代 JavaScript 利用的动态模块打包器。那么 webpack 是怎么实现不同品种资源模块加载的呢? 没错就是通过 loader。loader 用于对模块的源代码进行转换。loader 能够使你在 import 或加载模块时预处理文件。 咱们带着上面几个问题,彻底吃透 loader ~ 二、为什么要应用 loaderwebpack 是如何加载资源模块的呢?咱们先试着用 webpack 间接打包我的项目中的 css 文件。 初始化一个 webpack 我的项目,目录如下: 在 src 目录下新建了一个 index.css 文件,这里新建这个文件的目标就是以 css 文件为入口,尝试应用 webpack 独自打包它。 /* index.css */body { margin: 0 auto; padding: 0 20px; width: 1000px; background-color: #ccc;}调整下 webpack 配置,让入口文件门路指定为 index.css 的门路。 // webpack.config.jsmodule.exports = { entry: "./src/index.css", output: { filename: "bundle.js", },};而后咱们到终端运行 npx webpack 命令,你会发现命令行会提醒 Module parse failed: Unexpected token (1:5) 模块解析谬误。 ...

November 4, 2022 · 3 min · jiezi

关于webpack:Webpack基础

Webpack根底Webpack从一个或多个入口(Entry)开始寻找相干的依赖关系来建设依赖图,而后辨认他们的内容,webpack通过加载器(Loader)来辨认模块的内容,再将内容整顿分类打包成不同的块,最初放到输入(Output)目录下。在这个过程中,能够应用一些有用的插件(Plugin)来辅助实现各种工作,例如注入环境变量、资产治理或打包优化等。 1.装置与运行首先计算机中必须事后装置好node.js运行环境,再装置webpack依赖。 npm install --save-dev webpack webpack-cli最初通过npx webpack即可执行打包工作。 2.外围配置从4.0.0版本开始,Webpack不用用一个配置文件去捆绑你的我的项目,默认状况下,webpack应用src/index.js作为入口,输入的包是dist/main.js文件,然而也能够具体地配置各项参数来适配各自的需要。 2.1创立配置文件这时候就须要在我的项目外面新增一个webpack.config.js文件,这里有个工具能够在线创立。 2.2多配置源能够依据不同的状况抉择不同的配置文件: "scripts": { "build": "webpack --config prod.config.js"}2.3编译指标通过设置target属性,指定webpack编译输入的文件在什么样的环境中运行。例如服务器、浏览器别离可设置成"target": "node"和"target": "web"。 2.4入口配置默认状况下应用./src/index.js 作为默认入口。若要配置其余入口,可通过设置配置文件的 entry 属性来实现: module.exports = { entry: './path/to/my/entry/file.js',};除了配置一个入口,还能够配置多个,多个入口就会对应多个输入,请确保每个输入的文件的名字要惟一,能够应用替换模版来确保名称的抵触。 { entry: { index: './index/file/path', print: './print/file/path' }}以上配置完当前,就会生成两个入口块index和print。默认状况的名字是main。 entry属性能承受的数据结构有:门路字符串、门路字符串的数组、对象构造。 对于entry对象的具体配置如下: dependOn: The entry points that the current entry point depends on. They must be loaded before this entry point is loaded.filename: Specifies the name of each output file on disk.import: Module(s) that are loaded upon startup.library: Specify library options to bundle a library from current entry.runtime: The name of the runtime chunk. When set, a new runtime chunk will be created. It can be set to false to avoid a new runtime chunk since webpack 5.43.0.publicPath: Specify a public URL address for the output files of this entry when they are referenced in a browser. Also, see output.publicPath.更多设置请查阅这里。 ...

November 3, 2022 · 4 min · jiezi

关于webpack:webpack高级配置

摇树(tree shaking)我次要是想说摇树失败的起因(tree shaking 失败的起因),先讲下摇树自身成果 什么是摇树?举个例子 首先 webpack.config.js配置 const webpack = require("webpack");/** * @type {webpack.Configuration} */module.exports = { mode: "production"};在固定 a.js 用esm导出,b.js用commonjs导出不变动 // a.jsexport function f1() { console.log("11111");}export function f2() { console.log("22222");}// b.jsexports.f3 = function () { console.log("33333");};exports.f4 = function () { console.log("44444");};例子1:import a.js 和 require b.js// index.jsimport { f1 } from "./a";import { f3 } from "./b";console.log(f1);console.log(f3);打包后果:a.j 和 b.js 都摇树了,只输入了 f1 和 f3。所以导入用import,导出esm和commonjs都能够 例子2:import a.js 和 import b.js// index.jsimport { f1 } from "./a";const { f3 } = require("./b");console.log(f1);console.log(f3);打包后果:a.js 摇,b.js 没摇,输入了 f1 、f3、f4。所以导入用require不胜利 ...

November 2, 2022 · 2 min · jiezi

关于webpack:一文彻底读懂webpack常用配置

开发环境const webpack = require("webpack");const path = require('path')module.exports = { // entry: { // a: './src/0706/a.js', // c: './src/0706/c.js', // }, entry: "./src/0707/reactDemo.js", output: { filename: '[name]_dist.js', path: path.resolve(__dirname, 'dist3'), }, mode: 'development', devtool: 'source-map', module: { rules: [ { test:/.js$/, use: 'babel-loader', }, { test: /.css$/, use: [ 'style-loader', 'css-loader' ] }, { test:/.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, { test: /.(png|jpg|gif|jpeg)$/, use: 'file-loader' }, { test: /.(png|jpg|jpeg|gif)$/, use: { loader: 'url-loader', options: { limit: 10240 * 10 } } }, { test: /.(woff|woff2|eot|ttf|otf)$/, use: 'file-loader' } ], }, // plugins: [ // new webpack.HotModuleReplacementPlugin() // ], // 在应用devServer的时候,如果hot为true的话,会主动帮咱们增加HotModuleReplacementPlugin // 如果应用本人实现的服务器,就须要本人增加 devServer: { contentBase: './dist3', hot: true }}生产环境const webpack = require("webpack");const MiniCssExtractPlugin = require('mini-css-extract-plugin');// minicssextractplugin 举荐应用cssminimizerwebpackplugin来压缩cssconst CssMinimizerPlugin = require('css-minimizer-webpack-plugin');// 依据模板生产html,并插入相应的chunk,同时也能够压缩htmlconst HtmlWebpackPlugin = require('html-webpack-plugin');// 革除构建产物的插件,留神这里的引入形式const { CleanWebpackPlugin } = require('clean-webpack-plugin');const path = require('path');module.exports = { // entry: { // a: './src/0706/a.js', // c: './src/0706/c.js', // }, entry: "./src/0707/reactDemo.js", output: { // 文件指纹 chunkhash chunk扭转就会从新生成 // hash 整个我的项目有文件扭转就会从新生成 // contenthash 文件内容扭转才会从新生成 filename: '[name]_[chunkhash:8].js', path: path.resolve(__dirname, 'dist3'), }, mode: 'production', optimization: { minimizer: [ // 压缩CSS new CssMinimizerPlugin(), // webpack5内置了terser-plugin,然而下面的插件会笼罩掉默认的terser-plugin,所以通过上面的一行来将默认的插件加回去 '...' ] }, module: { rules: [ { test:/.js$/, use: 'babel-loader', }, { test: /.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader' ] }, { test:/.less$/, use: [ // 应用miniCssExtractPlugin提取css后,这里须要替换成它的loader MiniCssExtractPlugin.loader, 'css-loader', 'less-loader' ] }, { test: /.(png|jpg|gif|jpeg)$/, use: { loader: 'file-loader', options: { name: '[name]_[hash:8].[ext]' } } }, { test: /.(png|jpg|jpeg|gif)$/, use: { loader: 'url-loader', options: { limit: 10240 * 10 } } }, { test: /.(woff|woff2|eot|ttf|otf)$/, use: 'file-loader' } ], }, plugins: [ new MiniCssExtractPlugin({ // 应用contenthash 这样如果只扭转了js的话css也无需从新生成 filename: '[name]_[contenthash:8].css' }), new HtmlWebpackPlugin({ // 模板所在门路 template: path.resolve(__dirname, 'src/index.html'), // 生成的html的名字 filename: 'index2.html', // 用到了哪个chunk // chunks: ['a'] // 压缩选项 minify: { html5: true, collapseWhitespace: true, preserveLineBreaks: false, minifyCSS: true, minifyJS: true, removeComments: true } }) ]}主动增加CSS前缀应用postcss-loader + autoprefixer增加postcss.config.js 新版本间接在webpack配置文件里增加会报错,所以须要写到一个独立的配置文件里module.exports = { plugins: [ require('autoprefixer')({ overrideBrowserslist: ['last 2 version', '>1%', 'ios 7'] }) ]}增加loader{ test: /.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader' // 这里为新加的loader ]},挪动端适配 css px主动转rem应用手淘lib-flexible 动静计算font-size参考webpack视频解说:进入学习// 将lib-flexible动态内联到html上,因为要最先执行计算// 在头部退出如下代码// 应用了raw-loader,相当于在对应的地位是插入字符串// 需注意raw-loader新老版本引入的差别<script type="text/javascript"<%=require('raw-loader!babel-loader!./node_modules/lib-flexible/flexible.js')%></script>应用px2rem-loader 将px转成rem{ test: /.less$/ use: [ 'style-loader', 'css-loader', 'less-loader', { loader: 'px2rem-loader', options: { // 以设计稿宽度750px为例,1rem = 75px remUnit: 75, // 转换后的小数点后保留位数 remPrecision: 8, } } ]}代码外面间接按设计稿一样写px// 上面的px最初会被转成em,如果有些非凡的中央不想转,可写成大写PX.box { width: 100px; height: 100px; // 写成大写则不会被转换 border: 1PX;}代码宰割利用splitChunks plugin将公共代码抽离optimization: { splitChunks: { cacheGroups: { vendors: { chunks: 'all', name: 'vendors', // 将react和react-dom提取出一个包 test: // }, common: { name: 'common', chunks: 'all', minSize: 0, // 被援用两次以上的提取出一个包 minChunks: 2 } } }}动静import 懒加载通过ES6的动静import + babel插件@babel/plugin-syntax-dynamic-import//babel配置里减少plugins: [ '@babel/plugin-syntax-dynamic-import']// 代码里按需引入import('xxx').then(res => res.default);webpack联合eslint以react为例,用到几个插件eslint eslint-plugin-import eslint-plugin-react eslint-plugin-jsx-a11y装置解析器babel-eslint用airbnb的规定,需装置eslint-config-airbnb装置eslint-loader减少eslint配置 eslintrc.jsmodule.exports = { // 应用babel-eslint作为解析器 "parser": "babel-eslint", // 继承airbnb的规定 "extends": ["airbnb"], // 指定环境,这样应用全局变量的时候不会报错 "env": { "browser": true, "node": true }, // 自定义规定笼罩默认规定 "rules": { // 应用4个空格缩进,否则error "indent": ["error", 4] }}webpack打包库代码写好后,webpack配置如下const path = require('path');module.exports = { // 同时提供未压缩和压缩的版本 entry: { 'mylibrary': './src/entry.js', 'mylibrary.min': './src/entry.js' }, output: { path: path.resolve(__dirname, 'lib'), // mylibrary.js mylibrary.min.js filename: '[name].js', // 对外裸露的库的名称 library: 'mylibrary', // 反对cjs, ejs, script脚本等引入形式 libraryTarget: 'umd', // 不加这个的话,应用的时候可能须要mylibrary.default libraryExport: 'default' }}增加terser-webpack-plugin进行压缩const TerserPlugin = require('terser-webpack-plugin'); ...

November 2, 2022 · 4 min · jiezi

关于webpack:你需要知道的webpack高频面试题

谈谈你对webpack的认识webpack是一个模块打包工具,能够应用它治理我的项目中的模块依赖,并编译输出模块所需的动态文件。它能够很好地治理、打包开发中所用到的HTML,CSS,JavaScript和动态文件(图片,字体)等,让开发更高效。对于不同类型的依赖,webpack有对应的模块加载器,而且会剖析模块间的依赖关系,最初合并生成优化的动态资源。 webpack的基本功能和工作原理?代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等代码宰割:提取多个页面的公共代码、提取首屏不须要执行局部的代码让其异步加载模块合并:在采纳模块化的我的项目有很多模块和文件,须要构建性能把模块分类合并成一个文件主动刷新:监听本地源代码的变动,主动构建,刷新浏览器代码校验:在代码被提交到仓库前须要检测代码是否符合规范,以及单元测试是否通过主动公布:更新完代码后,主动构建出线上公布代码并传输给公布零碎。webpack构建过程从entry里配置的module开始递归解析entry依赖的所有module每找到一个module,就会依据配置的loader去找对应的转换规则对module进行转换后,再解析出以后module依赖的module这些模块会以entry为单位分组,一个entry和其所有依赖的module被分到一个组Chunk最初webpack会把所有Chunk转换成文件输入在整个流程中webpack会在失当的机会执行plugin里定义的逻辑webpack打包原理将所有依赖打包成一个bundle.js,通过代码宰割成单元片段按需加载 什么是webpack,与gulp,grunt有什么区别webpack是一个模块打包工具,能够递归地打包我的项目中的所有模块,最终生成几个打包后的文件。区别:webpack反对代码宰割,模块化(AMD,CommonJ,ES2015),全局剖析什么是entry,output?entry 入口,通知webpack要应用哪个模块作为构建我的项目的终点,默认为./src/index.jsoutput 进口,通知webpack在哪里输入它打包好的代码以及如何命名,默认为./dist什么是loader,plugins?loader是用来通知webpack如何转换某一类型的文件,并且引入到打包出的文件中。plugins(插件)作用更大,能够打包优化,资源管理和注入环境变量什么是bundle,chunk,module?bundle是webpack打包进去的文件,chunk是webpack在进行模块的依赖剖析的时候,代码宰割进去的代码块。module是开发中的单个模块 如何主动生成webpack配置?能够用一些官网脚手架 webpack-clivue-cli// 首先装置npm install -g @vue/cli// 新建我的项目hellovue create hellonuxt-cli// 确保装置了npx,npx在npm5.2.0默认装置了// 新建我的项目hellonpx create-nuxt-app hellowebpack如何配置单页面和多页面的应用程序?单个页面module.exports = { entry: './path/to/my/entry/file.js'}多页面应用程序module.entrys = { entry: { pageOne: './src/pageOne/index.js', pageTwo: './src/pageTwo/index.js' }}webpack-dev-server和http服务器如nginx有什么区别?webpack-dev-server应用内存来存储webpack开发环境下的打包文件,并且能够应用模块热更新,相比传统http服务器开发更加简略高效,webpack视频解说:进入学习 什么是模块热更新?webpack的一个性能,能够使代码批改后不必刷新浏览器就自动更新,高级版的主动刷新浏览器 dev-server是怎么跑起来的webpack-dev-server反对两种模式来主动刷新页面 iframe模式(页面放在iframe中,当发送扭转时重载)无需额定配置,只有以这种格局url拜访即可。http://localhost:8080/webpack-dev-server/index.htmlinline模式(将webpack-dev-server的客户端入口增加到bundle中)inline模式下url不必发生变化,但启动inline模式分两种状况// 以命令行启动webpack-dev-server有两种形式// 形式1 在命令行中增加--inline命令// 形式2 在webpack-config.js增加devServer:{inline: true}// 以node.js API启动有两种形式// 形式1 增加webpack-dev-server/client?http://localhost:8080/到webpack配置的entry入口点config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");// 将<script src="http://localhost:8080/webpack-dev-server.js"></script>增加到html文件中应用过webpack外面哪些plugin和loaderloader babel-loader: 将ES6+转移成ES5-css-loader,style-loader:解析css文件,可能解释@import url()等file-loader:间接输入文件,把构建后的文件门路返回,能够解决很多类型的文件url-loader:打包图片// url-loader增强版的file-loader,小于limit的转为Base64,大于limit的调用file-loadernpm install url-loader -D// 应用module.exports = { module: { rules: [{ test: /\.(png|jpg|gif)$/, use: [{ loader: 'url-loader', options: { outputPath: 'images/', limit: 500 //小于500B的文件打包出Base64格局,写入JS } }] }] }}plugins ...

November 2, 2022 · 2 min · jiezi

关于webpack:webpack热更新原理面试大概率会问

搭建webpack环境创立一个我的项目mkdir dev-erver && cd dev-servernpm init -y // 疾速创立一个我的项目配置npm i webpack webpack-dev-server webpack-cli --save-devmkdir src // 创立资源目录mkdir dist // 输入目录touch webpack.dev.js // 因为是在开发环境须要热更新,所以间接创立dev配置文件目录构造 webpack版本这里阐明一下,webpack4和webpack5的配置信息或者显示信息可能有点区别 "devDependencies": { "webpack": "^5.74.0", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.9.3" }编写配置文件// webpack.dev.js'use strict';const path = require('path');module.exports = { entry: './src/index.js', // 入口文件 output: { path: path.resolve(__dirname, 'dist'), // 输入到哪个文件夹 filename: 'output.js' // 输入的文件名 }, mode: 'development', // 开发模式 devServer: { // contentBase: path.resolve(__dirname, 'dist') // contentBase是用来指定被拜访html页面所在目录的; //然而我本地报错了,应用上面的语句 static: path.resolve(__dirname, "dist") }};新建文件// src/index.js'use strict' document.write('hello world~')package.json增加一条命令 "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack-dev-server --config webpack.dev.js --open" },npm run dev 运行 ...

November 1, 2022 · 2 min · jiezi

关于webpack:webpack配置优化让你的构建速度飞起

前言越来越多的我的项目应用webpack5来构建我的项目了,明天给大家带来最前沿的webpack5配置,让咱们代码在编译/运行时性能更好~咱们会从以下角度来进行优化: 晋升打包构建速度缩小代码体积优化代码运行性能晋升打包构建速度在进行打包速度优化之前,须要对以后我的项目每个局部的打包工夫理解分明。 咱们借助 speed-measure-webpack-plugin 插件,它剖析 webpack 的总打包耗时以及每个 plugin 和 loader 的打包耗时,从而让咱们对打包工夫较长的局部进行针对性优化。通过以下命令装置插件: yarn add speed-measure-webpack-plugin -D build就能看到各个局部的打包耗时 放大构建范畴 构建过程是默认全局查找,这十分的耗时。通过手动配置rules中的文件查找范畴,能够缩小打包的范畴,从而晋升打包的速度。 在webpack.config.js文件中如下配置: module.exports = { // ... module: { rules: [ { test: /.js$/, use: ['babel-loader'], exclude: /node_modules/, }, ], },};因为babel-loader对文件的转化是十分耗时的,所以放大构建范畴首先就是放大须要babel-loader解决的文件范畴。 能够通过 test 、 include 、 exclude 三个配置项来命中 Loader 要利用规定的文件,用include去命中须要被babel-loader解决的文件,exclude去排除不须要被解决的文件,从而放大了 Loader 解决文件的范畴。 HotModuleReplacement开发时咱们批改了其中一个模块代码,Webpack 默认会将所有模块全副从新打包编译,速度很慢。所以咱们须要做到批改某个模块代码,就只有这个模块代码须要从新打包编译,其余模块不变,这样打包速度就能很快。 HotModuleReplacement(HMR/热模块替换):在程序运行中,替换、增加或删除模块,而无需从新加载整个页面。 根本配置module.exports = { // 其余省略 devServer: { host: "localhost", // 启动服务器域名 port: "3000", // 启动服务器端口号 open: true, // 是否主动关上浏览器 hot: true, // 开启HMR性能(只能用于开发环境,生产环境不须要了) },};此时 css 款式通过 style-loader 解决,曾经具备 HMR 性能了。 然而 js 还不行。 ...

November 1, 2022 · 14 min · jiezi

关于webpack:webpack配置完全指南

前言对于入门选手来讲,webpack 配置项很多很重,如何疾速配置一个可用于线上环境的 webpack 就是一件值得思考的事件。其实相熟 webpack 之后会发现很简略,根底的配置能够分为以下几个方面: entry 、 output 、 mode 、 resolve 、 module 、 optimization 、 plugin 、 source map 、 performance 等,本文就来重点剖析下这些局部。 一、配置入口 entry1、单入口和多入口将源文件退出到 webpack 构建流程,能够是单入口: module.exports = { entry: `./index.js`,}构建包名称 [name]为 main ; 或多入口: module.exports = { entry: { "index": `./index.js`, },}key:value 键值对的模式: key:构建包名称,即 [name] ,在这里为 indexvalue:入口门路入口决定 webapck 从哪个模块开始生成依赖关系图(构建包),每一个入口文件都对应着一个依赖关系图。 2. 动静配置入口文件动静打包所有子项目当构建我的项目蕴含多个子项目时,每次减少一个子系统都须要将入口文件写入 webpack 配置文件中,其实咱们让webpack 动静获取入口文件,例如: // 应用 glob 等工具应用若干通配符,运行时取得 entry 的条目module.exports = { entry: glob.sync('./project/**/index.js').reduce((acc, path) => { const entry = path.replace('/index.js', '') acc[entry] = path return acc }, {}),}则会将所有匹配 ./project/**/index.js 的文件作为入口文件进行打包,如果你想要减少一个子项目,仅仅须要在 project 创立一个子项目目录,并创立一个 index.js 作为入口文件即可。 ...

November 1, 2022 · 8 min · jiezi

关于webpack:Webpack配置实战

前言本篇将从实际登程,搭建一个根底的反对模块化开发的我的项目,在第二章节《进阶配置》中应用 webpack 搭建一个 SASS + TS + React 的我的项目。 一、根底配置接下来一起配置一个根底的 Webpack。 将反对以下性能: 拆散开发环境、生产环境配置;模块化开发;sourceMap 定位正告和谬误;动静生成引入 bundle.js 的 HTML5 文件;实时编译;封装编译、打包命令。1. 新建我的项目新建一个空我的项目: // 新建 webpack-demo 文件夹mkdir webpack-demo// 进入 webpack-demo 目录cd ./webpack-demo// 初始化我的项目npm init -y新建 2 个 js 文件,并进行模块化开发: // 进入我的项目目录cd ./webpack-demo// 创立 src 文件夹mkdir src// 创立 js文件touch index.jstouch hello.jsindex.js: // index.jsimport './hello.js'console.log('index')hello.js: // hello.jsconsole.log('hello webpack')我的项目构造如下: - src - index.js - hello.js- package.json- node_modules2. 装置装置 NodeNode 须要是最新版本,举荐应用 nvm 来治理 Node 版本。 将 Node.js 更新到最新版本,也有助于进步性能。除此之外,将你的 package 管理工具(例如 npm 或者 yarn)更新到最新版本,也有助于进步性能。较新的版本可能建设更高效的模块树以及进步解析速度。我装置的版本信息如下: ...

October 31, 2022 · 6 min · jiezi

关于webpack:webpack实战手写loader和plugin

序言对于 webpack 来说, loader 和 plugin 能够算是需要水平最为宽泛的配置项了。然而呢,单单止步于配置可能还不够。如果咱们本人有时候想要 diy 一个需要,然而 webpack 又没有相干的 loader 和 plugin 。那这个时候咱们可能就得开始造点轮子来供应本人应用了。 因而,在明天的文章当中,将率领大家手写一个繁难的 loader 和 plugin ,并学会如何在我的项目中使用本人所编写的 loader 和 plugin 。 一起来学习吧~ 一、如何编写一个Loader1. 碎碎念之前的文章中咱们讲到了对于 loader 的一些配置。那如果把那些援用的 loader 改为咱们写的 loader ,该怎么解决呢? 当初,咱们来理解一下,如何手写一个繁难的 loader ,并使用到咱们的我的项目当中。 2. 我的项目构造首先用一张图,来看咱们的我的项目构造。如下图所示: 其中 loaders 文件夹下搁置咱们想要写的 loader ,同时外面的 replaceLoader.js 文件搁置咱们行将要写的 loader 的代码逻辑。之后,index.js 文件是咱们的入口文件,搁置咱们的业务逻辑。 webpack.config.js 文件搁置对于 webpack 的相干配置,而 dist 文件夹内的内容,搁置的是咱们通过 webpack 打包后,生成的打包文件。 3. 业务代码编写(1)入口文件代码当初,咱们先来编写入口文件 index.js 的代码。具体代码如下: console.log('hello monday');(2)编写loader入口文件的内容很简略,咱们想要达到的目标就是输入 hello monday 这个语句。当初,咱们来编写 loader 的内容,已达到对入口文件 index.js 的内容进行批改。 replaceLoader.js 文件的代码具体如下: ...

October 31, 2022 · 3 min · jiezi

关于webpack:webpack模块化的原理

commonjs在webpack中既能够书写commonjs模块也能够书写es模块,而且不必思考浏览器的兼容性问题,咱们来剖析一下原理。 首先搞清楚commonjs模块化的解决形式,简略配置一下webpack,写两个模块编译一下看一下: webpack.config.js module.exports = { mode: "development", devtool: "none"}index.js const a = require('./a')console.log(a)a.js const a = 'a';module.exports = a;编译后果查看编译后果,能够发现webpack对于每个模块的做法相似于node,将每个模块放在一个函数环境中并向其中传入一些必要的参数。webpack将这些模块组成一个对象(属性名是模块门路(模块id),属性值为模块内容)传入一个立刻执行函数,立刻执行函数中定义了一个函数 __webpack_require__相似node中的require函数,实现了导入模块的作用。 打包后果中删去了一些正文和临时用不要的代码,能够很显著的看进去实现commonjs模块化的要害就是这个 __webpack_require__ 函数,通过传入模块id来失去模块的导出。 require 函数__webpack_require__ 函数的实现: function __webpack_require__(moduleId) { // Check if module is in cache if (installedModules[moduleId]) { return installedModules[moduleId].exports; } // Create a new module (and put it into the cache) var module = installedModules[moduleId] = { i: moduleId, l: false, exports: {} }; // Execute the module function modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // Flag the module as loaded module.l = true; // Return the exports of the module return module.exports;}如果相熟node就很容易了解这个函数了: ...

October 31, 2022 · 3 min · jiezi

关于webpack:Webpack最佳实践

先简略回顾下 webpack 原理 Webpack 能够看做是模块打包机,把解析的所有模块变成一个对象,而后通过入口模块去加载咱们的货色,而后顺次实现递归的依赖关系,通过入口来运行所有的文件。因为 webpack 只意识js,所以须要通过一系列的 loader 和 plugin 转换成适合的格局供浏览器运行。 loader 次要是对资源进行加载/转译的预处理工作,其本质是一个函数,在该函数中对接管到的内容进行转换,返回转换后的后果。某种类型的资源能够应用多个 loader,执行程序是从右到左,从下到上。plugin(插件)次要是扩大 webpack 的性能,其本质是监听整个打包的生命周期。webpack 基于事件流框架 Tapable, 运行的生命周期中会播送出很多事件,plugin 能够监听这些事件,在适合的机会通过 webpack 提供的 API 扭转输入后果。webpack 装置新建一个目录,进入目录初始化 package.json,并装置 webpack 依赖 // 初始化包npm init -y// 装置依赖npm i webpack webpack-cli -D根底配置webpack 默认配置文件名字为 webpack.config.js,于是在我的项目根目录下新建一个名为 webpack.config.js 的文件,在配置文件里写最简略的单页面配置: let path = require("path");module.exports = { mode: "development", entry: "./src/js/index.js", output: { filename: "js/bundle.js", path: path.resolve("dist"), publicPath: "http://cdn.xxxxx" }}配置详解 mode - 打包模式 development 为开发模式,打包后代码不会被压缩production 为生产模式,打包后代码为压缩代码entry - 入口文件output - 打包文件配置 ...

October 27, 2022 · 7 min · jiezi

关于webpack:Webpack构建速度优化

前言当咱们的我的项目越来越大,webpack的配置项越来越多时,构建速度会越来越慢,所以咱们须要通过一些配置来进步webpack的构建速度。 目录放大范畴noParseIgnorePlugin优化 resolve 配置externals缓存放大范畴在配置 loader 的时候,咱们须要更准确的去指定 loader 的作用目录或者须要排除的目录,通过应用 include 和 exclude 两个配置项,能够实现这个性能,常见的例如: include:符合条件的模块进行解析exclude:排除符合条件的模块,不解析,优先级更高这样一来,一开始构建,咱们就能去除一些选项,比方,在应用babel-loader的时候 { test: /\.jsx?$/, use: [ { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/react'], plugins: [[require('@babel/plugin-proposal-decorators'), { legacy: true }]], cacheDirectory: true, // 启用缓存 }, }, ], include: path.resolve(__dirname, 'src'), exclude: /node_modules/, },noParse对于咱们引入的一些第三方包,比方jQuery,在这些包外部是必定不会依赖别的包,所以基本不须要webpack去解析它外部的依赖关系,应用 noParse 进行疏忽的模块文件中不会解析 import、require 等语法 module:{ noParse:/jquery|lodash/}IgnorePlugin有很多的第三方包外部会做国际化解决,蕴含很多的语言包,而这些语言包对咱们来说时没有多大用处的,只会增大包的体积,咱们齐全能够疏忽掉这些语言包,从而进步构建效率,减小包的体积。 用法 requestRegExp 示意要疏忽的门路。contextRegExp 示意要疏忽的文件夹目录。new webpack.IgnorePlugin({ resourceRegExp, contextRegExp });以moment为例,首先找到moment中语言包所在的文件夹,而后在webpack配置文件中增加插件 new webpack.IgnorePlugin(/./locale/, /moment/)也能够写成 new webpack.IgnorePlugin({resourceRegExp: /^\.\/locale$/,contextRegExp: /moment$/,}),这时候moment应用默认语言英语,如果要应用别的语言,能够手动引入须要应用的语言包。 import moment from 'moment'import 'moment/locale/zh-cn'moment.locale('zh-CN')优化 resolve 配置aliasalias 用的创立 import 或 require 的别名,用来简化模块援用,我的项目中根本都须要进行配置。 ...

October 27, 2022 · 2 min · jiezi

关于webpack:Webpack中的高级特性

自从webpack4当前,官网帮咱们集成了很多个性,比方在生产模式下代码压缩主动开启等,这篇文章咱们一起来探讨一下webpack给咱们提供的高级个性助力开发。 摸索webpack的高级个性个性:treeShaking顾名思义treeShaking,就是摇树,那么体现在代码模块外面就是摇掉那些没有被内部成员援用的代码,指的留神的是在生产环境下treeShaking会主动开启。 treeShaking初体验比方咱们在代码中引入lodash库,咱们只用到了once办法,那对于lodash其余的功能模块,在生产环境下打包,并不会输入到bundle.js文件外面,比方咱们在bundle.js外面去找lodash的一个办法debounce,他是齐全能够找失去的。 delelopment模式下打包的bundle.js production模式下打包的bundle.js 在这里你可能会说了production模式下会开启n多插件,解决打包后果,怎么就能阐明是treeShaking做的呢,的确这种做法不能阐明是treeShaking做的,咱们能够把mode设置为none再试一下,不过这里须要咱们手动去开启treeShaking,开启的形式如下。 // webpack.config.jsmodule.exports = { ... optimization: { usedExports: true, // 只导出内部成员援用模块 // 此属性用于模块导入合并,因为独自的模块导入要应用_webpack_require_函数。 // 此属性就是能够利用_webpack_require_一次性导入所有模块,也叫作用域晋升。 concatenateModules: true, minimize: true, // 开启代码压缩 } ...}none模式下打包的bundle.js所以none模式下,打包的后果仍然如此。 扩大因为treeShaking是依赖于ESM的,如果我的项目中有配合应用babel-loader那么treeShaking是不是会生效呢?咱们能够在配置文件外面增加babel-loader来辅以测试。 // 装置npm i babel-loader @babel/core @babel/preset-env -D// webpack.config.jsmodule.exports = { ... module:[ { test:/\.js$/, use:{ loader:'babel-loader', options:{ presets:[ ['@babel/preset-env'] ] } } } ]}文件成果咱们能够看到没有应用的代码,仍然是被移除掉了。 起因剖析因为babel-loader禁用了对ESM转化插件,所以通过babel-loader解决生成的仍旧是ESM代码,如果你想应用代码转换性能,那你就须要像上面这样配置,只不过这样treeShaking就会生效了。 // 装置npm i babel-loader @babel/core @babel/preset-env -D// webpack.config.jsmodule.exports = { ... module:{ rules:[ { test:/\.js$/, use:{ loader:'babel-loader', options:{ presets:[ // 强制应用commonjs转换 ['@babel/preset-env', {modules: 'commonjs'}] ] } } } ] }}那么treeShaking生效了,应该怎么办?不要怕,即便生效了还会有其余插件提供了相似treeShaking性能,比方代码压缩。 ...

October 26, 2022 · 3 min · jiezi

关于webpack:Webpack完整打包流程分析

前言webpack 在前端工程畛域起到了中流砥柱的作用,了解它的外部实现机制会对你的工程建设提供很大的帮忙(不论是定制性能还是优化打包)。 上面咱们基于 webpack5 源码构造,对整个打包流程进行简略梳理并进行实现,便与思考和了解每个阶段所做的事件,为今后扩大和定制工程化能力打下基础。 一、筹备工作在流程剖析过程中咱们会简略实现 webpack 的一些性能,局部性能的实现会借助第三方工具: tapable 提供 Hooks 机制来接入插件进行工作;babel 相干依赖可用于将源代码解析为 AST,进行模块依赖收集和代码改写。// 创立仓库mkdir webpack-demo && cd webpack-demo && npm init -y// 装置 babel 相干依赖npm install @babel/parser @babel/traverse @babel/types @babel/generator -D// 装置 tapable(注册/触发事件流)和 fs-extra 文件操作依赖npm install tapable fs-extra -D接下来咱们在 src 目录下新建两个入口文件和一个公共模块文件: mkdir src && cd src && touch entry1.js && touch entry2.js && touch module.js并别离为文件增加一些内容: // src/entry1.jsconst module = require('./module');const start = () => 'start';start();console.log('entry1 module: ', module);// src/entry2.jsconst module = require('./module');const end = () => 'end';end();console.log('entry2 module: ', module);// src/module.jsconst name = 'cegz';module.exports = { name,};有了打包入口,咱们再来创立一个 webpack.config.js 配置文件做一些根底配置: ...

October 26, 2022 · 9 min · jiezi

关于webpack:2022webpack5实战教程

前言手摸手教你如何打包,让你在入手的实际过程中感触webpack。 在入手之前,你可先简略理解一下webpack的概念 每一小结都有对应的分支,不便大家学习 webpack版本:5.58.1 入门新建一个目录,初始化npm npm init 接下来装置webpack和webpack-cli两个包 npm i -D webpack webpack-cli 默认配置新建一个文件夹src ,外面新建一个main.js,写一点测试代码 console.log("webpack") 在package.json中scripts中增加新的命令 "scripts": { "build": "webpack ./src/main.js"},执行打包命令npm run build 此时如果生成了一个dist文件夹,并且外部含有main.js阐明曾经打包胜利了 这个例子只是webpack本人默认的配置,上面咱们要实现更加丰盛的自定义配置 自定义配置新建一个build文件夹,外面新建一个webpack.config.js const path = require('path');module.exports = { mode:'development', // 开发模式 entry: path.resolve(__dirname,'../src/main.js'), // 入口文件 output: { filename: 'output.js', // 打包后的文件名称 path: path.resolve(__dirname,'../dist') // 打包后的目录 }}更改打包命令 { // ... "scripts": { "build": "webpack --config build/webpack.config.js" },}而后执行 npm run build,会失去如下后果 其中main.js是咱们第一次打包遗留的。 js曾经打包好了,接下来咱们要做的就是将js引入到html文件中 增加js到html文件咱们须要html-webpack-plugin来帮咱们实现这件事件 npm i -D html-webpack-plugin 新建一个与build同级的文件夹public,外面新建一个index.html 配置如下 ...

October 25, 2022 · 4 min · jiezi

关于webpack:Webpack中的plugin插件机制

大家有没有遇到过这些问题: webpack 打包之后的文件没有压缩动态文件要手动拷贝到输入目录代码中写了很多环境判断的多余代码上一篇 「webpack 外围个性」loader 说到 webpack 的 loader 机制,本文次要聊一聊另外一个外围个性:插件(plugin)。 插件机制就是为了实现我的项目中除了资源模块打包以外的其余自动化工作,解决上述的问题。 plugin 是用来扩大 webpack 性能的,通过在构建流程里注入钩子实现,它为 webpack 带来了很大的灵活性。 plugin 绝对于 loader 有哪些区别?loader 是转换器,将一种文件编译转换为另一个文件,操作的是文件。例如:将 .less 文件转换成 .css 文件。 plugin 是扩展器,它是针对 loader 完结之后,打包的整个过程。它并不间接操作文件,而是基于事件机制工作。在 webpack 构建流程中的特定时机会播送对应的事件,插件能够监听这些事件的产生,在特定的机会做对应的事件。包含:打包优化,资源管理,注入环境变量。 plugin 该怎么配置呢?例如 HtmlWebpackPlugin 能够为咱们生成一个 HTML 文件,其中包含应用 script 标签的 body 中的所有模块。看下如何配置: const HtmlWebpackPlugin = require('html-webpack-plugin');const webpackConfig = { ... plugins: [new HtmlWebpackPlugin()]};舒适提醒:loader 在 module.rules 中配置,作为模块的解析规定,类型为数组。每一项都是一个对象,外部蕴含了 test(类型文件)、loader、options(参数)等属性。plugin 则独自配置,类型为数组,每一项是一个 plugin 的实例,参数都通过构造函数传入。有哪些常见的 plugin?上面整顿的插件列表来自 webpack 中武官网,大家看见不相熟的 plugin 能够点击名称跳转,看一看,理解一下具体玩法。 名称形容AggressiveSplittingPlugin将原来的 chunk 分成更小的 chunkBabelMinifyWebpackPlugin应用 babel-minify进行压缩BannerPlugin在每个生成的 chunk 顶部增加 bannerCommonsChunkPlugin提取 chunks 之间共享的通用模块CompressionWebpackPlugin事后筹备的资源压缩版本,应用 Content-Encoding 提供拜访服务ContextReplacementPlugin重写 require 表达式的推断上下文CopyWebpackPlugin将单个文件或整个目录复制到构建目录DefinePlugin容许在编译时(compile time)配置的全局常量DllPlugin为了极大缩小构建工夫,进行 dll 分包EnvironmentPluginDefinePlugin 中 process.env 键的简写形式。ExtractTextWebpackPlugin从 bundle 中提取文本(CSS)到独自的文件HotModuleReplacementPlugin启用模块热替换(Enable Hot Module Replacement - HMR)HtmlWebpackPlugin简略创立 HTML 文件,用于服务器拜访I18nWebpackPlugin为 bundle 减少国际化反对IgnorePlugin从 bundle 中排除某些模块LimitChunkCountPlugin设置 chunk 的最小/最大限度,以微调和管制 chunkLoaderOptionsPlugin用于从 webpack 1 迁徙到 webpack 2MinChunkSizePlugin确保 chunk 大小超过指定限度NoEmitOnErrorsPlugin在输入阶段时,遇到编译谬误跳过NormalModuleReplacementPlugin替换与正则表达式匹配的资源NpmInstallWebpackPlugin在开发时主动装置短少的依赖ProvidePlugin不用通过 import/require 应用模块SourceMapDevToolPlugin对 source map 进行更细粒度的管制EvalSourceMapDevToolPlugin对 eval source map 进行更细粒度的管制UglifyjsWebpackPlugin能够管制我的项目中 UglifyJS 的版本ZopfliWebpackPlugin通过 node-zopfli 将资源事后压缩的版本怎么写一个 plugin?在说怎么写插件之前,先简略介绍几个好玩的货色:tapable、compiler 和 compilation。 ...

October 25, 2022 · 3 min · jiezi

关于webpack:Webpack完整打包流程分析

前言webpack 在前端工程畛域起到了中流砥柱的作用,了解它的外部实现机制会对你的工程建设提供很大的帮忙(不论是定制性能还是优化打包)。 上面咱们基于 webpack5 源码构造,对整个打包流程进行简略梳理并进行实现,便与思考和了解每个阶段所做的事件,为今后扩大和定制工程化能力打下基础。 一、筹备工作在流程剖析过程中咱们会简略实现 webpack 的一些性能,局部性能的实现会借助第三方工具: tapable 提供 Hooks 机制来接入插件进行工作;babel 相干依赖可用于将源代码解析为 AST,进行模块依赖收集和代码改写。// 创立仓库mkdir webpack-demo && cd webpack-demo && npm init -y// 装置 babel 相干依赖npm install @babel/parser @babel/traverse @babel/types @babel/generator -D// 装置 tapable(注册/触发事件流)和 fs-extra 文件操作依赖npm install tapable fs-extra -D接下来咱们在 src 目录下新建两个入口文件和一个公共模块文件: mkdir src && cd src && touch entry1.js && touch entry2.js && touch module.js并别离为文件增加一些内容: // src/entry1.jsconst module = require('./module');const start = () => 'start';start();console.log('entry1 module: ', module);// src/entry2.jsconst module = require('./module');const end = () => 'end';end();console.log('entry2 module: ', module);// src/module.jsconst name = 'cegz';module.exports = { name,};有了打包入口,咱们再来创立一个 webpack.config.js 配置文件做一些根底配置: ...

October 21, 2022 · 9 min · jiezi

关于webpack:Webpack插件核心原理

引言围绕 Webpack 打包流程中最外围的机制就是所谓的 Plugin 机制。 所谓插件即是 webpack 生态中最要害的局部, 它为社区用户提供了一种强有力的形式来间接涉及 webpack 的编译过程(compilation process)。 明天,咱们来聊聊 Webpack 中必不可少的外围 Plugin 机制 ~ Plugin实质上在 Webpack 编译阶段会为各个编译对象初始化不同的 Hook ,开发者能够在本人编写的 Plugin 中监听到这些 Hook ,在打包的某个特定时间段触发对应 Hook 注入特定的逻辑从而实现本人的行为。 对于 Plugin 中的 Hook 外部齐全是基于 tapable 来实现Plugin 中的罕用对象首先让咱们先来看看 Webpack 中哪些对象能够注册 Hook : compiler Hookcompilation HookContextModuleFactory HookJavascriptParser HooksNormalModuleFactory Hooks别放心,兴许对于这 5 个对象当初你会感觉到十分生疏,之后我会逐渐带你攻克它们。插件的根本形成咱们先来看这样一个最简略的插件,它会在 compilation(编译)实现时执行输入 done : class DonePlugin { apply(compiler) { // 调用 Compiler Hook 注册额定逻辑 compiler.hooks.done.tap('Plugin Done', () => { console.log('compilation done'); }); }}module.exports = DonePlugin;此时,在 compilation 实现时打包终端会打印进去一行 compilation done。 ...

October 21, 2022 · 3 min · jiezi

关于webpack:Webpack中的plugin插件机制

大家有没有遇到过这些问题: webpack 打包之后的文件没有压缩动态文件要手动拷贝到输入目录代码中写了很多环境判断的多余代码上一篇 「webpack 外围个性」loader 说到 webpack 的 loader 机制,本文次要聊一聊另外一个外围个性:插件(plugin)。 插件机制就是为了实现我的项目中除了资源模块打包以外的其余自动化工作,解决上述的问题。 plugin 是用来扩大 webpack 性能的,通过在构建流程里注入钩子实现,它为 webpack 带来了很大的灵活性。 plugin 绝对于 loader 有哪些区别?loader 是转换器,将一种文件编译转换为另一个文件,操作的是文件。例如:将 .less 文件转换成 .css 文件。 plugin 是扩展器,它是针对 loader 完结之后,打包的整个过程。它并不间接操作文件,而是基于事件机制工作。在 webpack 构建流程中的特定时机会播送对应的事件,插件能够监听这些事件的产生,在特定的机会做对应的事件。包含:打包优化,资源管理,注入环境变量。 plugin 该怎么配置呢?例如 HtmlWebpackPlugin 能够为咱们生成一个 HTML 文件,其中包含应用 script 标签的 body 中的所有模块。看下如何配置: const HtmlWebpackPlugin = require('html-webpack-plugin');const webpackConfig = { ... plugins: [new HtmlWebpackPlugin()]};舒适提醒:loader 在 module.rules 中配置,作为模块的解析规定,类型为数组。每一项都是一个对象,外部蕴含了 test(类型文件)、loader、options(参数)等属性。plugin 则独自配置,类型为数组,每一项是一个 plugin 的实例,参数都通过构造函数传入。有哪些常见的 plugin?上面整顿的插件列表来自 webpack 中武官网,大家看见不相熟的 plugin 能够点击名称跳转,看一看,理解一下具体玩法。 名称形容AggressiveSplittingPlugin将原来的 chunk 分成更小的 chunkBabelMinifyWebpackPlugin应用 babel-minify进行压缩BannerPlugin在每个生成的 chunk 顶部增加 bannerCommonsChunkPlugin提取 chunks 之间共享的通用模块CompressionWebpackPlugin事后筹备的资源压缩版本,应用 Content-Encoding 提供拜访服务ContextReplacementPlugin重写 require 表达式的推断上下文CopyWebpackPlugin将单个文件或整个目录复制到构建目录DefinePlugin容许在编译时(compile time)配置的全局常量DllPlugin为了极大缩小构建工夫,进行 dll 分包EnvironmentPluginDefinePlugin 中 process.env 键的简写形式。ExtractTextWebpackPlugin从 bundle 中提取文本(CSS)到独自的文件HotModuleReplacementPlugin启用模块热替换(Enable Hot Module Replacement - HMR)HtmlWebpackPlugin简略创立 HTML 文件,用于服务器拜访I18nWebpackPlugin为 bundle 减少国际化反对IgnorePlugin从 bundle 中排除某些模块LimitChunkCountPlugin设置 chunk 的最小/最大限度,以微调和管制 chunkLoaderOptionsPlugin用于从 webpack 1 迁徙到 webpack 2MinChunkSizePlugin确保 chunk 大小超过指定限度NoEmitOnErrorsPlugin在输入阶段时,遇到编译谬误跳过NormalModuleReplacementPlugin替换与正则表达式匹配的资源NpmInstallWebpackPlugin在开发时主动装置短少的依赖ProvidePlugin不用通过 import/require 应用模块SourceMapDevToolPlugin对 source map 进行更细粒度的管制EvalSourceMapDevToolPlugin对 eval source map 进行更细粒度的管制UglifyjsWebpackPlugin能够管制我的项目中 UglifyJS 的版本ZopfliWebpackPlugin通过 node-zopfli 将资源事后压缩的版本怎么写一个 plugin?在说怎么写插件之前,先简略介绍几个好玩的货色:tapable、compiler 和 compilation。 ...

October 21, 2022 · 3 min · jiezi

关于webpack:深度解读Webpack中的loader原理

一、前言webpack 是一个古代 JavaScript 利用的动态模块打包器。那么 webpack 是怎么实现不同品种资源模块加载的呢? 没错就是通过 loader。loader 用于对模块的源代码进行转换。loader 能够使你在 import 或加载模块时预处理文件。 咱们带着上面几个问题,彻底吃透 loader ~ 二、为什么要应用 loaderwebpack 是如何加载资源模块的呢?咱们先试着用 webpack 间接打包我的项目中的 css 文件。 初始化一个 webpack 我的项目,目录如下: 在 src 目录下新建了一个 index.css 文件,这里新建这个文件的目标就是以 css 文件为入口,尝试应用 webpack 独自打包它。 /* index.css */body { margin: 0 auto; padding: 0 20px; width: 1000px; background-color: #ccc;}调整下 webpack 配置,让入口文件门路指定为 index.css 的门路。 // webpack.config.jsmodule.exports = { entry: "./src/index.css", output: { filename: "bundle.js", },};而后咱们到终端运行 npx webpack 命令,你会发现命令行会提醒 Module parse failed: Unexpected token (1:5) 模块解析谬误。 ...

October 21, 2022 · 3 min · jiezi

关于webpack:Webpack中的高级特性

自从webpack4当前,官网帮咱们集成了很多个性,比方在生产模式下代码压缩主动开启等,这篇文章咱们一起来探讨一下webpack给咱们提供的高级个性助力开发。 摸索webpack的高级个性个性:treeShaking顾名思义treeShaking,就是摇树,那么体现在代码模块外面就是摇掉那些没有被内部成员援用的代码,指的留神的是在生产环境下treeShaking会主动开启。 treeShaking初体验比方咱们在代码中引入lodash库,咱们只用到了once办法,那对于lodash其余的功能模块,在生产环境下打包,并不会输入到bundle.js文件外面,比方咱们在bundle.js外面去找lodash的一个办法debounce,他是齐全能够找失去的。 delelopment模式下打包的bundle.js production模式下打包的bundle.js 在这里你可能会说了production模式下会开启n多插件,解决打包后果,怎么就能阐明是treeShaking做的呢,的确这种做法不能阐明是treeShaking做的,咱们能够把mode设置为none再试一下,不过这里须要咱们手动去开启treeShaking,开启的形式如下。 // webpack.config.jsmodule.exports = { ... optimization: { usedExports: true, // 只导出内部成员援用模块 // 此属性用于模块导入合并,因为独自的模块导入要应用_webpack_require_函数。 // 此属性就是能够利用_webpack_require_一次性导入所有模块,也叫作用域晋升。 concatenateModules: true, minimize: true, // 开启代码压缩 } ...}none模式下打包的bundle.js所以none模式下,打包的后果仍然如此。 扩大因为treeShaking是依赖于ESM的,如果我的项目中有配合应用babel-loader那么treeShaking是不是会生效呢?咱们能够在配置文件外面增加babel-loader来辅以测试。 // 装置npm i babel-loader @babel/core @babel/preset-env -D// webpack.config.jsmodule.exports = { ... module:[ { test:/\.js$/, use:{ loader:'babel-loader', options:{ presets:[ ['@babel/preset-env'] ] } } } ]}文件成果咱们能够看到没有应用的代码,仍然是被移除掉了。 起因剖析因为babel-loader禁用了对ESM转化插件,所以通过babel-loader解决生成的仍旧是ESM代码,如果你想应用代码转换性能,那你就须要像上面这样配置,只不过这样treeShaking就会生效了。 // 装置npm i babel-loader @babel/core @babel/preset-env -D// webpack.config.jsmodule.exports = { ... module:{ rules:[ { test:/\.js$/, use:{ loader:'babel-loader', options:{ presets:[ // 强制应用commonjs转换 ['@babel/preset-env', {modules: 'commonjs'}] ] } } } ] }}那么treeShaking生效了,应该怎么办?不要怕,即便生效了还会有其余插件提供了相似treeShaking性能,比方代码压缩。 ...

October 21, 2022 · 3 min · jiezi

关于webpack:Webpack构建速度优化

前言当咱们的我的项目越来越大,webpack的配置项越来越多时,构建速度会越来越慢,所以咱们须要通过一些配置来进步webpack的构建速度。 目录放大范畴noParseIgnorePlugin优化 resolve 配置externals缓存放大范畴在配置 loader 的时候,咱们须要更准确的去指定 loader 的作用目录或者须要排除的目录,通过应用 include 和 exclude 两个配置项,能够实现这个性能,常见的例如: include:符合条件的模块进行解析exclude:排除符合条件的模块,不解析,优先级更高这样一来,一开始构建,咱们就能去除一些选项,比方,在应用babel-loader的时候 { test: /\.jsx?$/, use: [ { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/react'], plugins: [[require('@babel/plugin-proposal-decorators'), { legacy: true }]], cacheDirectory: true, // 启用缓存 }, }, ], include: path.resolve(__dirname, 'src'), exclude: /node_modules/, },noParse对于咱们引入的一些第三方包,比方jQuery,在这些包外部是必定不会依赖别的包,所以基本不须要webpack去解析它外部的依赖关系,应用 noParse 进行疏忽的模块文件中不会解析 import、require 等语法 module:{ noParse:/jquery|lodash/}IgnorePlugin有很多的第三方包外部会做国际化解决,蕴含很多的语言包,而这些语言包对咱们来说时没有多大用处的,只会增大包的体积,咱们齐全能够疏忽掉这些语言包,从而进步构建效率,减小包的体积。 用法 requestRegExp 示意要疏忽的门路。contextRegExp 示意要疏忽的文件夹目录。new webpack.IgnorePlugin({ resourceRegExp, contextRegExp });以moment为例,首先找到moment中语言包所在的文件夹,而后在webpack配置文件中增加插件 new webpack.IgnorePlugin(/./locale/, /moment/)也能够写成 new webpack.IgnorePlugin({resourceRegExp: /^\.\/locale$/,contextRegExp: /moment$/,}),这时候moment应用默认语言英语,如果要应用别的语言,能够手动引入须要应用的语言包。 import moment from 'moment'import 'moment/locale/zh-cn'moment.locale('zh-CN')优化 resolve 配置aliasalias 用的创立 import 或 require 的别名,用来简化模块援用,我的项目中根本都须要进行配置。 ...

October 18, 2022 · 2 min · jiezi

关于webpack:webpack高级配置

摇树(tree shaking)我次要是想说摇树失败的起因(tree shaking 失败的起因),先讲下摇树自身成果 什么是摇树?举个例子 首先 webpack.config.js配置 const webpack = require("webpack");/** * @type {webpack.Configuration} */module.exports = { mode: "production"};在固定 a.js 用esm导出,b.js用commonjs导出不变动 // a.jsexport function f1() { console.log("11111");}export function f2() { console.log("22222");}// b.jsexports.f3 = function () { console.log("33333");};exports.f4 = function () { console.log("44444");};例子1:import a.js 和 require b.js// index.jsimport { f1 } from "./a";import { f3 } from "./b";console.log(f1);console.log(f3);打包后果:a.j 和 b.js 都摇树了,只输入了 f1 和 f3。所以导入用import,导出esm和commonjs都能够 例子2:import a.js 和 import b.js// index.jsimport { f1 } from "./a";const { f3 } = require("./b");console.log(f1);console.log(f3);打包后果:a.js 摇,b.js 没摇,输入了 f1 、f3、f4。所以导入用require不胜利 ...

October 18, 2022 · 2 min · jiezi

关于webpack:教你手写webpack常用loader

前言webpack 作为目前支流的前端构建工具,咱们简直每天都须要与它打交道。集体认为一个好的开源产品壮大的起因应该包含外围开发者的稳固输入以及对应生态的凋敝。对于生态来说, webpack 是一个足够凋谢的类库,提供了可插拔的形式去自定义一些配置,包含配置 loader 和 plugin ,本篇咱们次要探讨loader。 loader 实质上是一个函数,webpack在打包过程中会依照规定顺序调用解决某种文件的 loader ,而后将上一个 loader 产生的后果或者资源文件传入进去,以后 loader 解决实现后再交给下一个 loader 。 loader的类型开始之前,还是要先大略提一下 loader 的类型以及一些罕用的 api ,不感兴趣的同学能够间接跳过这一大节,更具体的指引请参阅官网文档。 loader 次要有以下几种类型: 同步 loader : return 或调用 this.callback 都是同步返回值异步 loader :是用 this.async() 获取异步函数,是用 this.callback() 返回值raw loader :默认状况下承受 utf-8 类型的字符串作为入参,若标记 raw 属性为 true ,则入参的类型为二进制数据pitch loader : loader 总是从右到左被调用。有些状况下,loader 只关怀 request 前面的 元数据(metadata),并且疏忽前一个 loader 的后果。在理论(从右到左)执行 loader 之前,会先从左到右调用 loader 上的 pitch 办法。开发 loader 时罕用的 API 如下: this.async :获取一个 callback 函数,解决异步this.callback :同步 loader 中,返回的办法this.emitFile :产生一个文件this.getOptions :依据传入的 schema 获取对应参数this.importModule :用于子编译器在构建时编译和执行申请this.resourcePath :以后资源文件的门路Hello Loader当初假如咱们有这么一个需要:在每个文件的头部打上开发者的相干信息。比方打包之前的文件内容是这样的: ...

October 18, 2022 · 7 min · jiezi

关于webpack:一文彻底读懂webpack常用配置

开发环境const webpack = require("webpack");const path = require('path')module.exports = { // entry: { // a: './src/0706/a.js', // c: './src/0706/c.js', // }, entry: "./src/0707/reactDemo.js", output: { filename: '[name]_dist.js', path: path.resolve(__dirname, 'dist3'), }, mode: 'development', devtool: 'source-map', module: { rules: [ { test:/.js$/, use: 'babel-loader', }, { test: /.css$/, use: [ 'style-loader', 'css-loader' ] }, { test:/.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, { test: /.(png|jpg|gif|jpeg)$/, use: 'file-loader' }, { test: /.(png|jpg|jpeg|gif)$/, use: { loader: 'url-loader', options: { limit: 10240 * 10 } } }, { test: /.(woff|woff2|eot|ttf|otf)$/, use: 'file-loader' } ], }, // plugins: [ // new webpack.HotModuleReplacementPlugin() // ], // 在应用devServer的时候,如果hot为true的话,会主动帮咱们增加HotModuleReplacementPlugin // 如果应用本人实现的服务器,就须要本人增加 devServer: { contentBase: './dist3', hot: true }}生产环境const webpack = require("webpack");const MiniCssExtractPlugin = require('mini-css-extract-plugin');// minicssextractplugin 举荐应用cssminimizerwebpackplugin来压缩cssconst CssMinimizerPlugin = require('css-minimizer-webpack-plugin');// 依据模板生产html,并插入相应的chunk,同时也能够压缩htmlconst HtmlWebpackPlugin = require('html-webpack-plugin');// 革除构建产物的插件,留神这里的引入形式const { CleanWebpackPlugin } = require('clean-webpack-plugin');const path = require('path');module.exports = { // entry: { // a: './src/0706/a.js', // c: './src/0706/c.js', // }, entry: "./src/0707/reactDemo.js", output: { // 文件指纹 chunkhash chunk扭转就会从新生成 // hash 整个我的项目有文件扭转就会从新生成 // contenthash 文件内容扭转才会从新生成 filename: '[name]_[chunkhash:8].js', path: path.resolve(__dirname, 'dist3'), }, mode: 'production', optimization: { minimizer: [ // 压缩CSS new CssMinimizerPlugin(), // webpack5内置了terser-plugin,然而下面的插件会笼罩掉默认的terser-plugin,所以通过上面的一行来将默认的插件加回去 '...' ] }, module: { rules: [ { test:/.js$/, use: 'babel-loader', }, { test: /.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader' ] }, { test:/.less$/, use: [ // 应用miniCssExtractPlugin提取css后,这里须要替换成它的loader MiniCssExtractPlugin.loader, 'css-loader', 'less-loader' ] }, { test: /.(png|jpg|gif|jpeg)$/, use: { loader: 'file-loader', options: { name: '[name]_[hash:8].[ext]' } } }, { test: /.(png|jpg|jpeg|gif)$/, use: { loader: 'url-loader', options: { limit: 10240 * 10 } } }, { test: /.(woff|woff2|eot|ttf|otf)$/, use: 'file-loader' } ], }, plugins: [ new MiniCssExtractPlugin({ // 应用contenthash 这样如果只扭转了js的话css也无需从新生成 filename: '[name]_[contenthash:8].css' }), new HtmlWebpackPlugin({ // 模板所在门路 template: path.resolve(__dirname, 'src/index.html'), // 生成的html的名字 filename: 'index2.html', // 用到了哪个chunk // chunks: ['a'] // 压缩选项 minify: { html5: true, collapseWhitespace: true, preserveLineBreaks: false, minifyCSS: true, minifyJS: true, removeComments: true } }) ]}主动增加CSS前缀应用postcss-loader + autoprefixer增加postcss.config.js 新版本间接在webpack配置文件里增加会报错,所以须要写到一个独立的配置文件里module.exports = { plugins: [ require('autoprefixer')({ overrideBrowserslist: ['last 2 version', '>1%', 'ios 7'] }) ]}增加loader{ test: /.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader' // 这里为新加的loader ]},挪动端适配 css px主动转rem应用手淘lib-flexible 动静计算font-size参考webpack视频解说:进入学习// 将lib-flexible动态内联到html上,因为要最先执行计算// 在头部退出如下代码// 应用了raw-loader,相当于在对应的地位是插入字符串// 需注意raw-loader新老版本引入的差别<script type="text/javascript"<%=require('raw-loader!babel-loader!./node_modules/lib-flexible/flexible.js')%></script>应用px2rem-loader 将px转成rem{ test: /.less$/ use: [ 'style-loader', 'css-loader', 'less-loader', { loader: 'px2rem-loader', options: { // 以设计稿宽度750px为例,1rem = 75px remUnit: 75, // 转换后的小数点后保留位数 remPrecision: 8, } } ]}代码外面间接按设计稿一样写px// 上面的px最初会被转成em,如果有些非凡的中央不想转,可写成大写PX.box { width: 100px; height: 100px; // 写成大写则不会被转换 border: 1PX;}代码宰割利用splitChunks plugin将公共代码抽离optimization: { splitChunks: { cacheGroups: { vendors: { chunks: 'all', name: 'vendors', // 将react和react-dom提取出一个包 test: // }, common: { name: 'common', chunks: 'all', minSize: 0, // 被援用两次以上的提取出一个包 minChunks: 2 } } }}动静import 懒加载通过ES6的动静import + babel插件@babel/plugin-syntax-dynamic-import//babel配置里减少plugins: [ '@babel/plugin-syntax-dynamic-import']// 代码里按需引入import('xxx').then(res => res.default);webpack联合eslint以react为例,用到几个插件eslint eslint-plugin-import eslint-plugin-react eslint-plugin-jsx-a11y装置解析器babel-eslint用airbnb的规定,需装置eslint-config-airbnb装置eslint-loader减少eslint配置 eslintrc.jsmodule.exports = { // 应用babel-eslint作为解析器 "parser": "babel-eslint", // 继承airbnb的规定 "extends": ["airbnb"], // 指定环境,这样应用全局变量的时候不会报错 "env": { "browser": true, "node": true }, // 自定义规定笼罩默认规定 "rules": { // 应用4个空格缩进,否则error "indent": ["error", 4] }}webpack打包库代码写好后,webpack配置如下const path = require('path');module.exports = { // 同时提供未压缩和压缩的版本 entry: { 'mylibrary': './src/entry.js', 'mylibrary.min': './src/entry.js' }, output: { path: path.resolve(__dirname, 'lib'), // mylibrary.js mylibrary.min.js filename: '[name].js', // 对外裸露的库的名称 library: 'mylibrary', // 反对cjs, ejs, script脚本等引入形式 libraryTarget: 'umd', // 不加这个的话,应用的时候可能须要mylibrary.default libraryExport: 'default' }}增加terser-webpack-plugin进行压缩const TerserPlugin = require('terser-webpack-plugin'); ...

October 18, 2022 · 4 min · jiezi

关于webpack:2022webpack5实战教程

前言手摸手教你如何打包,让你在入手的实际过程中感触webpack。 在入手之前,你可先简略理解一下webpack的概念 每一小结都有对应的分支,不便大家学习 webpack版本:5.58.1 入门新建一个目录,初始化npm npm init 接下来装置webpack和webpack-cli两个包 npm i -D webpack webpack-cli 默认配置新建一个文件夹src ,外面新建一个main.js,写一点测试代码 console.log("webpack") 在package.json中scripts中增加新的命令 "scripts": { "build": "webpack ./src/main.js"},执行打包命令npm run build 此时如果生成了一个dist文件夹,并且外部含有main.js阐明曾经打包胜利了 这个例子只是webpack本人默认的配置,上面咱们要实现更加丰盛的自定义配置 自定义配置新建一个build文件夹,外面新建一个webpack.config.js const path = require('path');module.exports = { mode:'development', // 开发模式 entry: path.resolve(__dirname,'../src/main.js'), // 入口文件 output: { filename: 'output.js', // 打包后的文件名称 path: path.resolve(__dirname,'../dist') // 打包后的目录 }}更改打包命令 { // ... "scripts": { "build": "webpack --config build/webpack.config.js" },}而后执行 npm run build,会失去如下后果 其中main.js是咱们第一次打包遗留的。 js曾经打包好了,接下来咱们要做的就是将js引入到html文件中 增加js到html文件咱们须要html-webpack-plugin来帮咱们实现这件事件 npm i -D html-webpack-plugin 新建一个与build同级的文件夹public,外面新建一个index.html 配置如下 ...

October 17, 2022 · 4 min · jiezi

关于webpack:Webpack配置实战

前言本篇将从实际登程,搭建一个根底的反对模块化开发的我的项目,在第二章节《进阶配置》中应用 webpack 搭建一个 SASS + TS + React 的我的项目。 一、根底配置接下来一起配置一个根底的 Webpack。 将反对以下性能: 拆散开发环境、生产环境配置;模块化开发;sourceMap 定位正告和谬误;动静生成引入 bundle.js 的 HTML5 文件;实时编译;封装编译、打包命令。1. 新建我的项目新建一个空我的项目: // 新建 webpack-demo 文件夹mkdir webpack-demo// 进入 webpack-demo 目录cd ./webpack-demo// 初始化我的项目npm init -y新建 2 个 js 文件,并进行模块化开发: // 进入我的项目目录cd ./webpack-demo// 创立 src 文件夹mkdir src// 创立 js文件touch index.jstouch hello.jsindex.js: // index.jsimport './hello.js'console.log('index')hello.js: // hello.jsconsole.log('hello webpack')我的项目构造如下: - src - index.js - hello.js- package.json- node_modules2. 装置装置 NodeNode 须要是最新版本,举荐应用 nvm 来治理 Node 版本。 将 Node.js 更新到最新版本,也有助于进步性能。除此之外,将你的 package 管理工具(例如 npm 或者 yarn)更新到最新版本,也有助于进步性能。较新的版本可能建设更高效的模块树以及进步解析速度。我装置的版本信息如下: ...

October 17, 2022 · 6 min · jiezi

关于webpack:Webpack最佳实践

先简略回顾下 webpack 原理先简略回顾下 webpack 原理 Webpack 能够看做是模块打包机,把解析的所有模块变成一个对象,而后通过入口模块去加载咱们的货色,而后顺次实现递归的依赖关系,通过入口来运行所有的文件。因为 webpack 只意识js,所以须要通过一系列的 loader 和 plugin 转换成适合的格局供浏览器运行。 loader 次要是对资源进行加载/转译的预处理工作,其本质是一个函数,在该函数中对接管到的内容进行转换,返回转换后的后果。某种类型的资源能够应用多个 loader,执行程序是从右到左,从下到上。plugin(插件)次要是扩大 webpack 的性能,其本质是监听整个打包的生命周期。webpack 基于事件流框架 Tapable, 运行的生命周期中会播送出很多事件,plugin 能够监听这些事件,在适合的机会通过 webpack 提供的 API 扭转输入后果。webpack 装置新建一个目录,进入目录初始化 package.json,并装置 webpack 依赖 // 初始化包npm init -y// 装置依赖npm i webpack webpack-cli -D根底配置webpack 默认配置文件名字为 webpack.config.js,于是在我的项目根目录下新建一个名为 webpack.config.js 的文件,在配置文件里写最简略的单页面配置: let path = require("path");module.exports = { mode: "development", entry: "./src/js/index.js", output: { filename: "js/bundle.js", path: path.resolve("dist"), publicPath: "http://cdn.xxxxx" }}配置详解 mode - 打包模式 development 为开发模式,打包后代码不会被压缩production 为生产模式,打包后代码为压缩代码entry - 入口文件output - 打包文件配置 ...

October 17, 2022 · 14 min · jiezi

关于webpack:webpack热更新原理面试大概率会问

搭建webpack环境创立一个我的项目mkdir dev-erver && cd dev-servernpm init -y // 疾速创立一个我的项目配置npm i webpack webpack-dev-server webpack-cli --save-devmkdir src // 创立资源目录mkdir dist // 输入目录touch webpack.dev.js // 因为是在开发环境须要热更新,所以间接创立dev配置文件目录构造 webpack版本这里阐明一下,webpack4和webpack5的配置信息或者显示信息可能有点区别 "devDependencies": { "webpack": "^5.74.0", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.9.3" }编写配置文件// webpack.dev.js'use strict';const path = require('path');module.exports = { entry: './src/index.js', // 入口文件 output: { path: path.resolve(__dirname, 'dist'), // 输入到哪个文件夹 filename: 'output.js' // 输入的文件名 }, mode: 'development', // 开发模式 devServer: { // contentBase: path.resolve(__dirname, 'dist') // contentBase是用来指定被拜访html页面所在目录的; //然而我本地报错了,应用上面的语句 static: path.resolve(__dirname, "dist") }};新建文件// src/index.js'use strict' document.write('hello world~')package.json增加一条命令 "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack-dev-server --config webpack.dev.js --open" },npm run dev 运行 ...

October 10, 2022 · 2 min · jiezi

关于webpack:webpack模块化的原理

commonjs在webpack中既能够书写commonjs模块也能够书写es模块,而且不必思考浏览器的兼容性问题,咱们来剖析一下原理。 首先搞清楚commonjs模块化的解决形式,简略配置一下webpack,写两个模块编译一下看一下: webpack.config.js module.exports = { mode: "development", devtool: "none"}index.js const a = require('./a')console.log(a)a.js const a = 'a';module.exports = a;编译后果查看编译后果,能够发现webpack对于每个模块的做法相似于node,将每个模块放在一个函数环境中并向其中传入一些必要的参数。webpack将这些模块组成一个对象(属性名是模块门路(模块id),属性值为模块内容)传入一个立刻执行函数,立刻执行函数中定义了一个函数 __webpack_require__相似node中的require函数,实现了导入模块的作用。 打包后果中删去了一些正文和临时用不要的代码,能够很显著的看进去实现commonjs模块化的要害就是这个 __webpack_require__ 函数,通过传入模块id来失去模块的导出。 require 函数__webpack_require__ 函数的实现: function __webpack_require__(moduleId) { // Check if module is in cache if (installedModules[moduleId]) { return installedModules[moduleId].exports; } // Create a new module (and put it into the cache) var module = installedModules[moduleId] = { i: moduleId, l: false, exports: {} }; // Execute the module function modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // Flag the module as loaded module.l = true; // Return the exports of the module return module.exports;}如果相熟node就很容易了解这个函数了: ...

October 10, 2022 · 3 min · jiezi

关于webpack:详解webpack构建优化

当我的项目越来越简单时,会面临着构建速度慢和构建进去的文件体积大的问题。webapck构建优化对于大我的项目是必须要思考的一件事,上面咱们就从速度和体积两方面来探讨构建优化的策略。 剖析工具在优化之前,咱们须要理解一些量化剖析的工具,应用它们来帮忙咱们剖析须要优化的点。 webpackbarwebpackbar能够在打包时实时显示打包进度。配置也很简略,在plugins数组中退出即可: const WebpackBar = require('webpackbar')module.exports = { plugins: [ ... new WebpackBar() ]}speed-measure-webpack-plugin应用speed-measure-webpack-plugin能够看到每个loader和plugin的耗时状况。 和一般插件的应用略有不同,须要用它的wrap办法包裹整个webpack配置项。 const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')const smp = new SpeedMeasurePlugin()module.exports = smp.wrap({ entry: './src/main.js', ...})打包后,在命令行的输入信息如下,咱们能够看出哪些loader和plugin耗时比拟久,而后对其进行优化。 webpack-bundle-analyzerwebpack-bundle-analyzer以可视化的形式让咱们直观地看到打包的bundle中到底蕴含哪些模块内容,以及每一个模块的体积大小。咱们能够依据这些信息去剖析我的项目构造,调整打包配置,进行优化。 在plugins数组中退出该插件。构建实现后,默认会在http://127.0.0.1:8888/展现剖析后果。 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPluginmodule.exports = { plugins: [ ... new BundleAnalyzerPlugin() ]} webpack-bundle-analyzer会计算出模块文件在三种情景下的大小: stat:文件未通过任何转换的原始大小parsed:文件通过转换后的输入大小(比方babel-loader转换ES6->ES5、UglifyJsPlugin压缩等等)gzip:parsed后的文件,通过Gzip压缩的大小应用speed-measure-webpack-plugin和webpack-bundle-analyzer自身也会减少打包工夫(webpack-bundle-analyzer特地耗时),所以倡议这两个插件在开发剖析时应用,而在生产环境去掉。 优化构建速度多过程构建运行在Node.js之上的 Webpack 是单线程的,就算有多个工作同时存在,它们也只能一个一个排队执行。当我的项目比较复杂时,构建就会比较慢。现在大多数CPU都是多核的,咱们能够借助一些工具,充沛开释 CPU 在多核并发方面的劣势。参考webpack视频解说:进入学习 比拟常见的有happypack、thread-loader。 happypackhappypack可能将构建工作合成给多个子过程去并发执行,子过程解决完后再把后果发送给主过程。应用配置如下,就是把原有的loader的配置转移到happyPack中去解决。 const Happypack = require('happypack')module.exports = { module:{ rules:[ { test: /\.js$/, use: 'happypack/loader?id=babel' //问号前面的查问参数指定了解决这类文件的HappyPack实例的名字 }, ] }, plugins:[ new Happypack({ id: 'babel', //HappyPack实例名,对应下面rules中的“id=babel” use: ['babel-loader'] //本来要应用的loader }) ]}thread-loaderhappypack的作者曾经没有这个我的项目进行保护了,在webpack4之后,能够应用thread-loader。 ...

October 10, 2022 · 2 min · jiezi

关于webpack:webpack配置优化让你的构建速度飞起

前言越来越多的我的项目应用webpack5来构建我的项目了,明天给大家带来最前沿的webpack5配置,让咱们代码在编译/运行时性能更好~咱们会从以下角度来进行优化: 晋升打包构建速度缩小代码体积优化代码运行性能晋升打包构建速度在进行打包速度优化之前,须要对以后我的项目每个局部的打包工夫理解分明。 咱们借助 speed-measure-webpack-plugin 插件,它剖析 webpack 的总打包耗时以及每个 plugin 和 loader 的打包耗时,从而让咱们对打包工夫较长的局部进行针对性优化。通过以下命令装置插件: yarn add speed-measure-webpack-plugin -D build就能看到各个局部的打包耗时 放大构建范畴 构建过程是默认全局查找,这十分的耗时。通过手动配置rules中的文件查找范畴,能够缩小打包的范畴,从而晋升打包的速度。 在webpack.config.js文件中如下配置: module.exports = { // ... module: { rules: [ { test: /.js$/, use: ['babel-loader'], exclude: /node_modules/, }, ], },};因为babel-loader对文件的转化是十分耗时的,所以放大构建范畴首先就是放大须要babel-loader解决的文件范畴。 能够通过 test 、 include 、 exclude 三个配置项来命中 Loader 要利用规定的文件,用include去命中须要被babel-loader解决的文件,exclude去排除不须要被解决的文件,从而放大了 Loader 解决文件的范畴。 HotModuleReplacement开发时咱们批改了其中一个模块代码,Webpack 默认会将所有模块全副从新打包编译,速度很慢。所以咱们须要做到批改某个模块代码,就只有这个模块代码须要从新打包编译,其余模块不变,这样打包速度就能很快。 HotModuleReplacement(HMR/热模块替换):在程序运行中,替换、增加或删除模块,而无需从新加载整个页面。 根本配置module.exports = { // 其余省略 devServer: { host: "localhost", // 启动服务器域名 port: "3000", // 启动服务器端口号 open: true, // 是否主动关上浏览器 hot: true, // 开启HMR性能(只能用于开发环境,生产环境不须要了) },};此时 css 款式通过 style-loader 解决,曾经具备 HMR 性能了。 然而 js 还不行。 ...

October 3, 2022 · 14 min · jiezi

关于webpack:webpack配置完全指南

概念 来看一下官网对webpack的定义: 实质上,webpack 是一个古代 JavaScript 应用程序的动态模块打包器(module bundler)。当 webpack 解决应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中蕴含应用程序须要的每个模块,而后将所有这些模块打包成一个或多个bundle。 首先webpack是一个动态模块打包器,所谓的动态模块,包含脚本、样式表和图片等等;webpack打包时首先遍历所有的动态资源,依据资源的援用,构建出一个依赖关系图,而后再将模块划分,打包出一个或多个bundle。再次白piao一下官网的图,活泼的形容了这个过程: 提到webpack,就不得不提webpack的四个外围概念 入口(entry):批示 webpack 应该应用哪个模块,来作为构建其外部依赖图的开始输入(output):在哪里输入它所创立的 bundlesloader:让 webpack 可能去解决那些非 JavaScript 文件插件(plugins):用于执行范畴更广的工作你的第一个打包器 咱们首先在全局装置webpack: npm install webpack webpack-cli –g webpack能够不应用配置文件,间接通过命令行构建,用法如下: webpack <entry> [<entry>] -o <output> 这里的entry和output就对应了上述概念中的入口和输出,咱们来新建一个入口文件: //demo1/index.jsvar a = 1console.log(a)document.write('hello webpack') 有了入口文件咱们还须要通过命令行定义一下输出门路dist/bundle.js: webpack index.js -o dist/bundle.js 这样webpack就会在dist目录生成打包后的文件。 咱们也能够在我的项目目录新建一个html引入打包后的bundle.js文件查看成果。 配置文件 命令行的打包形式仅限于简略的我的项目,如果咱们的我的项目较为简单,有多个入口,咱们不可能每次打包都把入口记下来;因而个别我的项目中都应用配置文件来进行打包;配置文件的命令形式如下: webpack [--config webpack.config.js] 配置文件默认的名称就是webpack.config.js,一个我的项目中常常会有多套配置文件,咱们能够针对不同环境配置不同的文件,通过--config来进行切换: //生产环境配置webpack --config webpack.prod.config.js//开发环境配置webpack --config webpack.dev.config.js相干webpack视频解说:进入学习多种配置类型 config配置文件通过module.exports导出一个配置对象: //webpack.config.jsvar path = require('path');module.exports = { mode: 'development', //入口文件 entry: './index.js', //输入目录 output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }}; 除了导出为对象,还能够导出为一个函数,函数中会带入命令行中传入的环境变量等参数,这样能够更不便的对环境变量进行配置;比方咱们在打包线上正式环境和线上开发环境能够通过env进行辨别: ...

October 3, 2022 · 5 min · jiezi

关于webpack:webpack实战手写loader和plugin

序言对于 webpack 来说, loader 和 plugin 能够算是需要水平最为宽泛的配置项了。然而呢,单单止步于配置可能还不够。如果咱们本人有时候想要 diy 一个需要,然而 webpack 又没有相干的 loader 和 plugin 。那这个时候咱们可能就得开始造点轮子来供应本人应用了。 因而,在明天的文章当中,将率领大家手写一个繁难的 loader 和 plugin ,并学会如何在我的项目中使用本人所编写的 loader 和 plugin 。 一起来学习吧~ 一、如何编写一个Loader1. 碎碎念之前的文章中咱们讲到了对于 loader 的一些配置。那如果把那些援用的 loader 改为咱们写的 loader ,该怎么解决呢? 当初,咱们来理解一下,如何手写一个繁难的 loader ,并使用到咱们的我的项目当中。 2. 我的项目构造首先用一张图,来看咱们的我的项目构造。如下图所示: 其中 loaders 文件夹下搁置咱们想要写的 loader ,同时外面的 replaceLoader.js 文件搁置咱们行将要写的 loader 的代码逻辑。之后,index.js 文件是咱们的入口文件,搁置咱们的业务逻辑。 webpack.config.js 文件搁置对于 webpack 的相干配置,而 dist 文件夹内的内容,搁置的是咱们通过 webpack 打包后,生成的打包文件。 相干webpack视频解说:进入学习3. 业务代码编写(1)入口文件代码当初,咱们先来编写入口文件 index.js 的代码。具体代码如下: console.log('hello monday');(2)编写loader入口文件的内容很简略,咱们想要达到的目标就是输入 hello monday 这个语句。当初,咱们来编写 loader 的内容,已达到对入口文件 index.js 的内容进行批改。 replaceLoader.js 文件的代码具体如下: ...

September 28, 2022 · 3 min · jiezi

关于webpack:手写一个webpack插件

前言前端性能优化是一个陈词滥调的话题,对于性能优化的技术文档和书籍都特地多。如果大家想深刻学习前端性能优化相干内容,有以下举荐 雅虎军规35条某东上搜“前端性能优化”,书籍也特地多。然而前端性能优化做的所有工作,都和一个灵魂拷问有极大的关系:在浏览器输出url后,产生了什么?首先url是一个域名,首先它要被解析成ip地址。如果你的设施之前拜访过该url,那么本地可能会缓存ip地址。如果没有缓存过,那么就向dns服务器进行解析。依据 IP 地址和默认端口建设TCP连贯,三次握手。浏览器收回HTTP申请;服务器对申请作出响应;此时兴许会有一些304之类的返回后果。会波及到http缓存机制。开释TCP连贯;浏览器将该html文本并显示内容。所以咱们能够从这个过程里去思考,服务器如何把文件尽快发送到客户浏览器。 第一点,就是文件尽可能要小,文件尽可能少,发送起来会更快第二点,就是发送过程,在肯定条件下,缩小文件或申请的个数。文件也并不是越少越好,假如文件内容少到极致,内容全副合并到一个文件,那么这个文件会是十分微小的,发送起来也会十分慢。如果文件个数太多,那么浏览器也会限度并发数量,在同一个域名下,浏览器的并发数量是6个。这样,尽管每个申请发送的文件很少,然而建设申请的过程也是耗时间的。很多申请都被阻塞了。以上是针对第一次拜访网站时可用的计划,然而如果一个网站常常被反复拜访,还有以下办法第三点,缓存机制 就是之前用到过的文件和内容,如果没有生效,就能够重复使用,不须要再从服务器拿。以上是我大略能想到的一些思路。如果有不精确的中央,或者有其余好的思路,心愿大家留言帮我补充。 上面咱们进入正题,说一下我在开发我的项目时遇到的一个问题,以及解决思路 开发过程遇到的一个理论问题在vue我的项目打包后,会在我的项目的根目录下生成一个dist(你也能够扭转该名称)文件夹。一个单页面利用的dist文件夹通常蕴含一个index.html 和 一个js文件夹 和一些其余资源文件。 而后咱们把dist文件夹公布到服务器上,在浏览器下来拜访咱们的我的项目,刚开始可能会特地慢。关上chrome调试工具,查看一下资源加载状况。 太惊人了,一个要害的js文件,在nginx服务器上曾经做了压缩解决,从800k压缩到270k左右。然而加载工夫仍然达到了惊人的22.89s。这个对于任何一个我的项目来说都是不可承受的。 相干webpack视频解说:进入学习初步解决思路问题曾经出现了。打包后的文件,呈现了特地大的js,而且就是这个js文件阻塞了整个我的项目的加载。因为最近正在钻研webpack相干内容。webpack大家应该都应用过。webpack是一个打包编译工具,它做的事件,就是把你开发的整个我的项目,编译成一个浏览器可间接辨认的我的项目。它蕴含以下一些根底概念: 1,入口文件入口文件,就是webpack工作的终点,从入口文件开始,咱们通常会import很多其余模块,import等模块化的开发方法,就把整个我的项目给串联起来了。依据这些依赖信息,webpack把整个我的项目解析为一个ast(形象语法树),这个树记录了所有的文件依赖门路。2,进口文件就是我的项目打包后寄存的目录,所有资源文件都会输入到这个文件夹3,loaderwebpack只能辨认es5的语法,对于es6等更新的语法,是不能辨认的,对于一些图片,css文件,jsx文件等各种不同后缀名的文件,都是须要loader进行解析的。loader做的事件也就是这些。4,plugin依据webpack官网文档,咱们晓得webpack在整个打包和编译的过程中,有几十个工夫节点。具体的内容能够看这个链接,在plugins目录下: webpack.docschina.org/api/compile…那么我做的一点小尝试,就是在文件打包并且输出到output文件夹后,找到要害的js文件(上图划红线的那个文件),上传到公司的阿里云oss。而后index.html文件本来是援用了output外面的js文件,改为援用oss外面的链接。这也是待会儿实现webpack自定义插件的次要思路。 最初的试验成果本来须要20多秒加载的文件,放到阿里云oss后,只须要0.5s的加载速度,是不是十分惊人呢。而后发现,影响页面加载的次要因素,曾经不是这个要害js了。咱们好能够在此基础根底上做其余优化。 插件代码 和 应用办法先看次要代码:在src目录下新建plugins文件夹,而后新建了一个UploadJsToCDNPlugin.js文件。这也是咱们的插件文件。 src/plugins/UploadJsToCDNPlugin.js 文件内容如下: // const globby = require('globby');const path = require('path');const fs = require('fs');const axios = require('axios')var FormData = require('form-data')let replaceFile = function(filePath,sourceRegx,targetStr){ fs.readFile(filePath,function(err,data){ if(err){ return err; } let str = data.toString(); str = str.replace(sourceRegx,targetStr); fs.writeFile(filePath, str, function (err) { if (err) return err; }); });}class UploadJsToCDNPlugin { constructor(options = {}) { this.options = options; } apply(compiler) { console.log(compiler.options.mode) compiler.hooks.afterEmit.tap('UploadJsToCDNPlugin', async (params) => { try { const js_path = Object.keys(params.assets).find(item => item.includes('js/chunk-libs.'))// 请自行调整文件名称 const html_path = path.resolve(compiler.options.output.path, 'index.html') const file_path = path.resolve(compiler.options.output.path, js_path) // 因为是公司我的项目,已做脱敏解决,道歉 const url = 'https://wwwxxxxxx/file/upload' const form = FormData() form.append('file', fs.createReadStream(file_path), { filename: 'app.js' }) const res = await axios.create({ headers: form.getHeaders() }) .post(url,form) const cdn_path = res.data.data // 这行代码是本插件的外围代码 await replaceFile(html_path, /js\/chunk-libs.\w*.js/g, cdn_path)// 请自行调整文件名称 } catch (e) { e } }) }}module.exports = UploadJsToCDNPlugin;最初在vue.config.js外面应用webpack自定义webpack插件:vue.config.js 文件结尾: ...

September 28, 2022 · 1 min · jiezi

关于webpack:你需要知道的webpack高频面试题

谈谈你对webpack的认识webpack是一个模块打包工具,能够应用它治理我的项目中的模块依赖,并编译输出模块所需的动态文件。它能够很好地治理、打包开发中所用到的HTML,CSS,JavaScript和动态文件(图片,字体)等,让开发更高效。对于不同类型的依赖,webpack有对应的模块加载器,而且会剖析模块间的依赖关系,最初合并生成优化的动态资源。 webpack的基本功能和工作原理?代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等代码宰割:提取多个页面的公共代码、提取首屏不须要执行局部的代码让其异步加载模块合并:在采纳模块化的我的项目有很多模块和文件,须要构建性能把模块分类合并成一个文件主动刷新:监听本地源代码的变动,主动构建,刷新浏览器代码校验:在代码被提交到仓库前须要检测代码是否符合规范,以及单元测试是否通过主动公布:更新完代码后,主动构建出线上公布代码并传输给公布零碎。webpack视频解说:进入学习webpack构建过程从entry里配置的module开始递归解析entry依赖的所有module每找到一个module,就会依据配置的loader去找对应的转换规则对module进行转换后,再解析出以后module依赖的module这些模块会以entry为单位分组,一个entry和其所有依赖的module被分到一个组Chunk最初webpack会把所有Chunk转换成文件输入在整个流程中webpack会在失当的机会执行plugin里定义的逻辑webpack打包原理将所有依赖打包成一个bundle.js,通过代码宰割成单元片段按需加载 什么是webpack,与gulp,grunt有什么区别webpack是一个模块打包工具,能够递归地打包我的项目中的所有模块,最终生成几个打包后的文件。区别:webpack反对代码宰割,模块化(AMD,CommonJ,ES2015),全局剖析什么是entry,output?entry 入口,通知webpack要应用哪个模块作为构建我的项目的终点,默认为./src/index.jsoutput 进口,通知webpack在哪里输入它打包好的代码以及如何命名,默认为./dist什么是loader,plugins?loader是用来通知webpack如何转换某一类型的文件,并且引入到打包出的文件中。plugins(插件)作用更大,能够打包优化,资源管理和注入环境变量什么是bundle,chunk,module?bundle是webpack打包进去的文件,chunk是webpack在进行模块的依赖剖析的时候,代码宰割进去的代码块。module是开发中的单个模块 如何主动生成webpack配置?能够用一些官网脚手架 webpack-clivue-cli// 首先装置npm install -g @vue/cli// 新建我的项目hellovue create hellonuxt-cli// 确保装置了npx,npx在npm5.2.0默认装置了// 新建我的项目hellonpx create-nuxt-app hellowebpack如何配置单页面和多页面的应用程序?单个页面module.exports = { entry: './path/to/my/entry/file.js'}多页面应用程序module.entrys = { entry: { pageOne: './src/pageOne/index.js', pageTwo: './src/pageTwo/index.js' }}webpack-dev-server和http服务器如nginx有什么区别?webpack-dev-server应用内存来存储webpack开发环境下的打包文件,并且能够应用模块热更新,相比传统http服务器开发更加简略高效 什么是模块热更新?webpack的一个性能,能够使代码批改后不必刷新浏览器就自动更新,高级版的主动刷新浏览器 dev-server是怎么跑起来的webpack-dev-server反对两种模式来主动刷新页面 iframe模式(页面放在iframe中,当发送扭转时重载)无需额定配置,只有以这种格局url拜访即可。http://localhost:8080/webpack-dev-server/index.htmlinline模式(将webpack-dev-server的客户端入口增加到bundle中)inline模式下url不必发生变化,但启动inline模式分两种状况// 以命令行启动webpack-dev-server有两种形式// 形式1 在命令行中增加--inline命令// 形式2 在webpack-config.js增加devServer:{inline: true}// 以node.js API启动有两种形式// 形式1 增加webpack-dev-server/client?http://localhost:8080/到webpack配置的entry入口点config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");// 将<script src="http://localhost:8080/webpack-dev-server.js"></script>增加到html文件中应用过webpack外面哪些plugin和loaderloader babel-loader: 将ES6+转移成ES5-css-loader,style-loader:解析css文件,可能解释@import url()等file-loader:间接输入文件,把构建后的文件门路返回,能够解决很多类型的文件url-loader:打包图片// url-loader增强版的file-loader,小于limit的转为Base64,大于limit的调用file-loadernpm install url-loader -D// 应用module.exports = { module: { rules: [{ test: /\.(png|jpg|gif)$/, use: [{ loader: 'url-loader', options: { outputPath: 'images/', limit: 500 //小于500B的文件打包出Base64格局,写入JS } }] }] }}plugins ...

September 26, 2022 · 2 min · jiezi

关于webpack:webpack配置完全指南

前言对于入门选手来讲,webpack 配置项很多很重,如何疾速配置一个可用于线上环境的 webpack 就是一件值得思考的事件。其实相熟 webpack 之后会发现很简略,根底的配置能够分为以下几个方面: entry 、 output 、 mode 、 resolve 、 module 、 optimization 、 plugin 、 source map 、 performance 等,本文就来重点剖析下这些局部。 内附一张 webpack 零配置比照图片,关注公众号【前端瓶子君】回复【webpack】收费获取pdf文件。 一、配置入口 entry1、单入口和多入口将源文件退出到 webpack 构建流程,能够是单入口: module.exports = { entry: `./index.js`,}构建包名称 [name]为 main ; 或多入口: module.exports = { entry: { "index": `./index.js`, },}key:value 键值对的模式: key:构建包名称,即 [name] ,在这里为 indexvalue:入口门路入口决定 webapck 从哪个模块开始生成依赖关系图(构建包),每一个入口文件都对应着一个依赖关系图。 webpack视频解说:进入学习2. 动静配置入口文件动静打包所有子项目当构建我的项目蕴含多个子项目时,每次减少一个子系统都须要将入口文件写入 webpack 配置文件中,其实咱们让webpack 动静获取入口文件,例如: // 应用 glob 等工具应用若干通配符,运行时取得 entry 的条目module.exports = { entry: glob.sync('./project/**/index.js').reduce((acc, path) => { const entry = path.replace('/index.js', '') acc[entry] = path return acc }, {}),}则会将所有匹配 ./project/**/index.js 的文件作为入口文件进行打包,如果你想要减少一个子项目,仅仅须要在 project 创立一个子项目目录,并创立一个 index.js 作为入口文件即可。 ...

September 26, 2022 · 8 min · jiezi

关于webpack:webpack把react编译成weapp

引言webpack@5.69.0之前应用taro@3.5.5创立一个taro-react我的项目之后build了一个weapp我的项目 最初一步就是启用webpack把react代码编译成weapp webpack入口在package.json中能够找到入口文件这个文件的作用就是引入webpack外围函数(lib/webpack.js)以及工具文件,抛出整顿好之后的webpack外围函数 "main": "lib/index.js",最终输入: // lib/index.js// mergeExports是解决fn的,最初输入的就是后果解决的fnmodule.exports = mergeExports(fn, { // 很多文件的引入 get webpack() { return require("./webpack"); // 外围文件 }, ......})mergeExports // lib/index.js// 第一个参数是对象(函数继承于Fuction,Fuction继承于Object)const mergeExports = (obj, exports) => { // 克隆exports对象,传入这个对象里有很多的文件的引入 const descriptors = Object.getOwnPropertyDescriptors(exports); // 遍历这个对象 for (const name of Object.keys(descriptors)) { const descriptor = descriptors[name]; if (descriptor.get) { const fn = descriptor.get; // 遍历出的属性一个个增加getter到传入的webpack函数 Object.defineProperty(obj, name, { configurable: false, enumerable: true, /** * memoize就是执行了传入的fn返回一个返回执行之后的后果的一个函数 * memoize(fn)等于 * function(){ * return fn(); * } */ get: memoize(fn) }); } else if (typeof descriptor.value === "object") { Object.defineProperty(obj, name, { configurable: false, enumerable: true, writable: false, value: mergeExports({}, descriptor.value) // 递归 }); } else { throw new Error( "Exposed values must be either a getter or an nested object" ); } } // 返回了一个解冻之后的对象,这个对象是个函数,函数外面有很多增加进去的属性办法 return /** @type {A & B} */ (Object.freeze(obj)); };打印descriptor能够失去如下 ...

September 17, 2022 · 3 min · jiezi

关于webpack:WebPack多入口配置

Webpack多入口配置不须要应用路由,而是通过多入口独立实现 1. React目录index.html:模板HTML;如果每个入口的模板HTML不统一,能够建设一个文件夹寄存。App.less:公共款式,如果没有,可省略global.d.ts:寄存一些全局的公共定义pages:下为多个文件夹,每个文件夹就是一个模块,内蕴含index.ts及对应的css文件 2. Webpack配置获取到每个模块的index.tsx并拼装成entry须要的格局应用html-webpack-plugin,进行HTML模板的创立,因为有多少个entry,就须要进行多少次new HtmlWebpackPlugin(),所以在生成entry处同步进行htmlPlugins的解决,在配置中进行应用 const getEntries = () => { // 每个模块的入口文件都是index.tsx const files = glob.sync('./app/pages/**/index.tsx'); files.forEach(element => { const file = element.split('/') const name = file[file.length - 2] entries[name] = element htmlPlugins.push(new HtmlWebpackPlugin({ title: 'Custom template', template: './app/index.html', filename: `${name}/index.html`, chunks: [name] })) })}entry: entries,plugins: [ ...htmlPlugins]js文件依照模块进行js文件的分类,并设置生成门路 output: { filename: '[name]/[name].js', path: path.resolve(__dirname, 'out', 'app',), chunkFilename: '[name].bundle.js',},默认会生成license.txt文件,正文则增加以下代码 optimization: { minimizer: [ new TerserPlugin({ extractComments: false }) ],}css文件 对less和css文件的解析,留神程序 如果不须要独自生成css文件,能够不应用MiniCssExtractPlugin, MiniCssExtractPlugin.loader替换为style-loader 对less文件的解决,只应用less-loader会报错,所以增加了options的配置 ...

September 16, 2022 · 1 min · jiezi

关于webpack:模块联邦插件中几个name的用法和关联

new ModuleFederationPlugin({ name: 'my_name', filename: 'remoteEntry.js' remotes: { // multiple 是外部应用的名称 // multiple_mf_v0_0_1 是内部模块的name,相当于这里的 my_name 'multiple': 'multiple_mf_v0_0_1@//localhost:9001/remoteEntry.js' }})其中 my_name 是裸露进来的名字,内部要应用这个模块时要这要引入 'innner_name':my_name@//localhost:9002/remoteEntry.js 具体应用的中央 import { xxx } from 'innner_name'

September 2, 2022 · 1 min · jiezi

关于webpack:webpack学习笔记webpack5

webpack,须要进行绝对应的练习,所以存在了 gitee 上,地址如下:https://gitee.com/one-reed-an...

August 14, 2022 · 1 min · jiezi

关于webpack:webpack基础优化

August 5, 2022 · 0 min · jiezi

关于webpack:WEB前端线上系统课2022最新已更新至916集day52实时更新中

download:WEB前端线上零碎课2022最新【已更新至916集day52实时更新中】手把手教你用 Jenkins 主动部署 SpringBootCI/CD 是一种通过在利用开发阶段引入自动化来频繁向客户托付利用的方法。CI/CD 的核心概念可能总结为三点: 继续集成继续托付继续部署 CI/CD 次要针对在集成新代码时所引发的问题(俗称"集成地狱")。为什么会有集成地狱这个“雅称”呢?大家想想咱们一个我的项目部署的过程,拉取代码->构建->测试->打包->部署,如果咱们常常需要部署我的项目,特地是在微服务期间,服务特地多的情况下,不停的测试打包部署,那估计得有集体一整天顺便做这事了,而这事又是繁琐的重复无意义的。具体而言,CI/CD 可让继续自动化和继续监控贯穿于利用的整个生命周期(从集成和测试阶段,到托付和部署),这些关联的事务通常被统称为"CI/CD 管道",由开发和运维团队以敏捷形式协同反对。1.1 CI(Continuous Integration)CI/CD 中的"CI"始终指继续集成,它属于开发人员的自动化流程。胜利的 CI 意味着利用代码的新更改会定期构建、测试并合并到代码仓库中,该解决打算可能解决在一次开发中有太多利用分支,从而导致相互冲突的问题。1.2 CD(Continuous Delivery/Continuous Deployment)CI/CD 中的"CD"指的是继续托付和/或继续部署,这些相干概念有时会交叉使用。两者都事关管道后续阶段的自动化,但它们有时也会独自使用,用于说明自动化程度。继续托付(Continuous Delivery)通常是指开发人员对利用的更改会主动进行谬误测试并上传到代码仓库(如 GitHub、GitLab 等),而后由运维团队将其部署到实时生产环境中。这旨在解决开发和运维团队之间可见性及沟通较差的问题。因此,继续托付的目标就是确保尽可能减少部署新代码时所需的工作量。继续部署(Continuous Deployment)指的是主动将开发人员的更改从代码仓库公布到生产环境,以供客户使用。通过一套全自动化的流程,来解决手动测试、编译、打包等操作。继续部署以继续托付的劣势为根基,实现了管道后续阶段的自动化。 什么是 Jenkins后面说的 CI/CD 算是一种思维,思维要落地,就需要对应的工具。Jenkins 是一款开源的 CI/CD 软件,可能算是 CI/CD 软件指导者,它提供了超过 1000 个插件来反对构建、部署、自动化,基本上能够满足任何我的项目的需要。整体来说,Jenkins 有如下六大个性:继续集成和继续托付 作为一个可扩大的自动化服务器,Jenkins 可能用作简略的 CI 服务器,或者变成任何我的项目的继续托付核心。 繁难安装 Jenkins 是一个基于 Java 的独立程序,可能立即运行,蕴含 Windows、Mac OS X 和其余类 Unix 操作系统。 配置简略 Jenkins 可能通过其网页界面轻松设置和配置,其中包含即时谬误检查和内置帮助。 插件 通过更新核心中的 1000 多个插件,Jenkins 集成了继续集成和继续托付工具链中几乎所有的工具。 扩大 Jenkins 可能通过其插件架构进行扩大,从而为 Jenkins 可能做的事提供几乎有限的可能性。 分布式 Jenkins 可能轻松地在多台机器上调配工作,帮助更疾速地跨多个平台推动构建、测试和部署。其实 Jenkins 有很多好玩的用法,明天我还是想先通过一个简略的案例,先来和大家捋一捋如何使用 Jenkins 来实现一个 Spring Boot 我的项目的主动公布部署,这样大家对 Jenkins 现有一个直观的认知,各种其余使用细节松哥在当前的文章中再来和大家细聊。 ...

August 4, 2022 · 1 min · jiezi

关于webpack:webpack优化

个别都要借助工具来可视化剖析可优化的点 例如:webpack-bundle-analyzer剖析出优先、重点优化的点 放大构建指标:exclude include 例如,exclude - node-modules include src上面的内容优化打包速度:tree-shaing代码剔除不进行打包splitChunkPlugin 对大文件进行拆分晋升打包速度css,js,image等压缩,配置响应的Loader,plugin进行压缩代码sourceMap 生产环境敞开

August 3, 2022 · 1 min · jiezi

关于webpack:webpack-核心-Compiler-实现系列一

webpack 外围 Compiler 实现Compiler 类是 webpack的运行入口,每次打包时,会生成一个实例,外面挂载了许多打包的数据,在这里简化了构造,力求理解关键性打包流程 1. Compiler类初始化解析 import 语句保留依赖图生成入口代码/** * 1. 定义 Compiler 类 */class Compiler { constructor(options) { const { entry, output } = options; this.entry = entry; this.output = output; this.modules = []; } // 构建启动 run(){} // 重写 require 函数,输入 Bundle generate() {}}2. Compiler 中的import导入解析webpack.config.js const path = require('path')module.exports = { // entry: path.resolve(__dirname, './src/index.js'), entry: './src/index.js', output: { path: path.resolve(__dirname, './dist'), filename: 'main.js' }}compiler.js ...

July 26, 2022 · 1 min · jiezi

关于webpack:webpack-和-webpackcli

webpack 的装置目前分为两个:webpack、webpack-cli webpack、webpack-cli 的区别在命令行中执行 webpack 命令,会执行 node_modules 下的 .bin 目录下的 webpack 文件,webpack 的执行依赖 webpack-cli,如果没有装置webpack-cli 就会报错。在 webpack-cli 中代码执行时,才是真正利用 webpack 进行编译和打包的过程; npm install webpack webpack-cli –g #全局装置npm install webpack webpack-cli –D #部分装置 (我的项目中应用)全局装置 和 部分装置 的区别?如果只有全局的 webpack,那么打包的时候,用了全局的 webpack,不同电脑的 webpack 版本不同会导致包的装置版本不同。部分装置:每一个我的项目都有本人的 webpack 的版本, –D 是开发时依赖,定义了对立的 webpack 版本,打包的时候不会呈现包的版本问题。间接在命令行中执行 webpack 找的是全局的 webpack,如果要用部分的 webpack 的话: 去 node_modules 中的 .bin 中找 webpack:./node_modules/.bin/webpack执行npx webpack默认找 node_modules 中的 .bin 下的 webpack 文件在 package.json 中写脚本 "build": "npx webpack",在应用的时候 npm run build 相当于执行了 webpack 指令。webpack 是如何确定咱们的入口的呢?当咱们运行 webpack 时,webpack 会查找当前目录下的 src/index.js 作为入口,如果没有存在 src/index.js 文件,就会报错。 ...

July 24, 2022 · 1 min · jiezi

关于webpack:webpack-拆包关于-splitChunks-的几个重点属性解析

为什么须要 splitChunks?先来举个简略的栗子,wepack 设置中有 3 个入口文件:a.js、b.js 和 c.js,每个入口文件都同步 import 了 m1.js,不设置 splitChunks,配置下 webpack-bundle-analyzer 插件用来查看输入文件的内容,打包输入是这样的: 从剖析图中能够比拟直观的看出,三个输入 bundle 文件中都蕴含了 m1.js 文件,这阐明有反复的模块代码。splitChunks 的目标就是用来把反复的模块代码拆散到独自的文件,以异步加载的形式来节俭输入文件的体积。splitChunks 的配置项很多而且感觉官网文档的一些形容不是很分明,上面通过一些重点配置属性和场景解释来帮忙大家了解和弄懂如何配置 splitChunks。为不便了解和简略演示,webpack 和 splitChunks 的初始设置如下: const path = require('path');const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;module.exports = { mode: 'development', entry: { a: './src/a.js', b: './src/b.js', c: './src/c.js', }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].bundle.js', clean: true, }, optimization: { splitChunks: { chunks: 'async', // 生成 chunk 的最小体积(以 bytes 为单位)。 // 因为演示的模块比拟小,须要设置这个。 minSize: 0, }, }, plugins: [new BundleAnalyzerPlugin()],};chunkssplitChunks.chunks 的作用是批示采纳什么样的形式来优化拆散 chunks,罕用的有三种罕用的取值:async、initial 和 all,async 是默认值,接下来别离看下这三种设置的区别。 ...

July 11, 2022 · 4 min · jiezi

关于webpack:webpack基础配置与css相关loader

本系列文章是我在学习webpack时的总结与播种,心愿我的一些学习内容能够帮忙到一些正在学习 webpack 的敌人。本片文章为系列文章的第二篇,蕴含 webpack 根底配置与 css 相干 loaderwebpack的应用(01篇内容补充)webpack装置形式: # 全局装置npm install webpack webpack-cli -g# 本地我的项目装置npm install webpack webpack-cli如果咱们间接在命令行中执行 webpack ,此时,它默认应用的全局装置的webpack以及webpack-cli,如果没有全局装置这两个货色,则就会报错如下: $ webpack --config wk.config.jsbash: webpack: command not found如果在全局也装置了雷同的依赖,那么咱们是能够间接执行该命令的 若想要应用本地我的项目中的 webpack、webpack-cli,有两种形式: npx webpack --config wk.config.js :该命令能够间接应用 node_modules/.bin/ 下的可执行文件,应用的就是本地装置的依赖npm run build :该命令会执行 package.json 文件中 scripts 下的 build 命令,此时会优先应用本地依赖,如果本地依赖不存在,则会应用全局依赖这一点也解释了很常见的一个面试题:为什么要运行 npm run xxx,而不间接运行其对应的指令 webpack 配置webpack 配置文件webpack 的默认配置文件为:webpack.config.js ,放在我的项目的根目录下。但其实,webpack(我应用的webpack5的版本)提供了三种默认配置文件的写法,均位于我的项目根目录下,自上而下优先级递加,如下所示: webpack.config.js.webpack/webpack.config.js.webpack/webpackfile.js如果不想应用默认配置文件,能够自定义配置文件,在package.json中,增加--config 自定义配置文件门路 "scripts": { "build": "webpack --config path"}在 webpack-cli/lib/webpack-cli.js 中能够查看到相应代码: if (options.config && options.config.length > 0) { // 读取自定义配置文件 // options.config 中蕴含自定义配置文件的门路 const loadedConfigs = await Promise.all( options.config.map((configPath) => { return loadConfigByPath(path.resolve(configPath), options.argv) } ), );} else { // 默认配置文件门路 // Order defines the priority, in decreasing order const defaultConfigFiles = [ "webpack.config", ".webpack/webpack.config", ".webpack/webpackfile" ]}自定义配置文件 ...

June 28, 2022 · 2 min · jiezi

关于webpack:项目性能优化之给dist文件夹中chunkvendorsjs做splitChunks分包从而减少首屏加载时间

问题形容咱们我的项目做完,验收通过当前,就须要打包公布上线啦。于是咱们执行命令:npm run build打dist包,打包完当前截图如下: 间接打包的chunk-vendors.js太大了 chunk-vendors.js文件太大了,所以咱们须要将其优化一下,拆分一下chunk-vendors.js是啥chunk-vendors.js,顾名思义chunk(块/包)-vendors(供应商),即为:不是本人写的模块包,也就是/node_modules我的项目目录的所有模块包。所以这个chunk-vendors.js文件大的起因其实就是,咱们把第三方的包都打包在这一个文件上了,都糅在一块,必定大啊,所以想方法把其做一个拆分。 应用optimization.splitChunks做分包咱们先看一下分包拆分当前打包的dist文件夹中的js文件大小 分包当前的效果图 这样的话,咱们就把chunk-vendors.js文件由,原来的824kB拆分成一个个几十KB的包文件了,这样的话,生产环境加载的时候,就会快一些splitChunks分包代码咱们以vue为例,在vue.config.js文件中退出以下代码。代码大家间接复制粘贴即可应用,也是笔者本人在生产环境中应用的哦。 configureWebpack: config => { if (process.env.NODE_ENV !== 'production') return return { plugins: [ // ...... ], // 看这里:把chunk-vendors.js进行分包,晋升资源加载速度,很有必要 optimization: { /** * runtimeChunk可选值有:true或'multiple'或'single' * true或'multiple'会有每个入口对应的chunk。不过个别状况下 * 思考到要模块初始化,设置为single就够少数状况下应用啦。 * 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationruntimechunk * */ runtimeChunk: 'single', /** * 以前是CommonsChunkPlugin,当初换成optimization.splitChunks。一般我的项目下方的配置就足够用啦 * 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationsplitchunks * */ splitChunks: { chunks: 'all', // 可选值:all,async 和 initial。all性能最弱小,所以咱们就应用all maxInitialRequests: Infinity, // 最大并行申请数,为了以防万一,设置无穷大即可 minSize: 20000, // 引入的模块大于20kb才做代码宰割,官网默认20000,这里不必批改了 maxSize: 60000, // 若引入的模块大于60kb,则通知webpack尝试再进行拆分 cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, // 应用正则匹配node_modules中引入的模块 priority: -10, // 优先级值越大优先级越高,默认-10,不必批改 name(module) { // 设定分包当前的文件模块名字,依照包名字替换拼接一下 const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1] return `npm.${packageName.replace('@', '')}` }, }, }, } } } },总结好忘性不如烂笔头,记录一下吧^_^ ...

June 22, 2022 · 1 min · jiezi

关于webpack:项目性能优化之用urlloader把小图片转base64大图片使用imagewebpackloader压缩

问题形容我的项目中经常会引入一些图片资源,什么jpg|jpeg|png|gif|ico之类的,失常状况下,咱们须要做一下性能优化,看看如何大而化小、小而化了,晋升生产环境资源加载速度。所以,本文记录一下大图片应用image-webpack-loader插件压缩一下、小图片应用url-loader转成base64格局,并比拟前后优化差异。以下代码是笔者在生产环境应用的,亲测无效。大家间接复制粘贴即可 url-loader的应用首先,url-loader和image-webpack-loader都依赖于file-loader,file-loader简言之就是一个资源加载模块,去找文件资源的loader,而后也能够给动态资源生成哈希值,即惟一标识身份证。个别不必配置。咱们次要是通过url-loader和image-webpack-loader做相干对应项配置 下载url-loader和file-loadercnpm i url-loader file-loader --save 应用url-loader转base64截图 未应用url-loader就是一般的图片加载,这里不赘述。咱们次要是看转成base64的成果;因为下方还要说image-webpack-loader,所以代码放在最初image-webpack-loader的应用下载image-webpack-loader这里大家留神,不要应用高版本的image-webpack-loader,否则可能呈现谬误,这里我应用的是6.0.0版本,大家能够应用这个版本。另外file-loader因为之前装置过了,所以,这里就不必装置了 cnpm i image-webpack-loader@6.0.0 --save 未应用image-webpack-loader截图 应用image-webpack-loader截图 比照两个图,咱们能够看到应用image-webpack-loader压缩后,无论是大小还是加载工夫,都优化了不少,所以这个loader还是能够的 两个loader的残缺代码以vue我的项目为例,在vue.config.js的chainWebpack加上以下代码即可 chainWebpack(config) { config.module.rule("images").test(/\.(jpg|jpeg|png|gif|ico)$/) // 给这些图片类型做压缩 .use("url-loader") // url-loader要搭配file-loader做图片压缩 .loader("url-loader") .options({ limit: 1024 * 12,// 小于12kb的图片压缩成base64,图片太大转成base64反而不太适合 name: "static/img/[name].[ext]"//指定打包后的图片寄存的地位,个别放在static下img文件夹里 name.ext别离为:文件名.文件后缀(依照原图片名) }) .end() // 返回上一级 以便于持续增加loader .use('image-webpack-loader') .loader("image-webpack-loader") .options({ disable: process.env.NODE_ENV == 'development' ? true : false, // 开发环境禁用压缩,生产环境才做压缩,晋升开发调试速度 mozjpeg: { quality: 60 }, // 压缩JPEG图像,压缩品质quality为60,范畴0到100 optipng: { enabled: true }, // 压缩PNG图像,enabled为true开启压缩 pngquant: { quality: [0.65, 0.90], speed: 4 }, // 品质区间和速度就应用默认值吧 gifsicle: { interlaced: false }, // Interlace gif for progressive rendering 默认false webp: { quality: 60 } // 压缩webp图片,压缩品质quality为60,范畴0到100 }) .end() // 返回上一级 持续增加loader .enforce('post') // 示意先执行配置在上面那个loader,即image-webpack-loader},总结具体配置项,要去npm或者github看看。不过上述一般配置项,基本上能解决大多数需要,勉强够用了 ...

June 20, 2022 · 1 min · jiezi

关于webpack:项目优化之使用compressionwebpackplugin插件开启gzip压缩以vue为例

问题形容本文以vue为例,记录一下,应用webpack插件compression-webpack-plugin开启gzip压缩的步骤流程,以及比照开启gzip压缩前后所须要的工夫,得出结论:**这个插件确实可能做性能优化,缩小加载的工夫**react也是同一个情理,在此不赘述 前端配置之vue.config.js配置第一步,下载compression-webpack-plugincnpm i compression-webpack-plugin@6.1.1 --save 留神,这里不能间接下载,须要下载低版本的。间接下载就是最新版的了,vue脚手架临时不反对最新版的,所以就会报错:TypeError: Cannot read property 'tapPromise' of undefined。我这里下载是指定@6.1.1版本,是能够用的第二步,vue.config.js应用下方代码,间接复制粘贴应用即可 const CompressionPlugin = require('compression-webpack-plugin');//引入gzip压缩插件// 裸露配置项,会被合并到webpack中去module.exports = { chainWebpack(config) { // ...... }, configureWebpack: config => { // 开发环境不配置 if (process.env.NODE_ENV !== 'production') return // 生产环境才去配置 return { plugins: [ new CompressionPlugin({ //此插件不能应用太高的版本,否则报错:TypeError: Cannot read property 'tapPromise' of undefined // filename: "[path][base].gz", // 这种形式是默认的,多个文件压缩就有多个.gz文件,倡议应用下方的写法 filename: '[path].gz[query]', // 使得多个.gz文件合并成一个文件,这种形式压缩后的文件少,倡议应用 algorithm: 'gzip', // 官网默认压缩算法也是gzip test: /\.js$|\.css$|\.html$|\.ttf$|\.eot$|\.woff$/, // 应用正则给匹配到的文件做压缩,这里是给html、css、js以及字体(.ttf和.woff和.eot)做压缩 threshold: 10240, //以字节为单位压缩超过此大小的文件,应用默认值10240吧 minRatio: 0.8, // 最小压缩比率,官网默认0.8 //是否删除原有动态资源文件,即只保留压缩后的.gz文件,倡议这个置为false,还保留源文件。以防: // 如果呈现拜访.gz文件拜访不到的时候,还能够拜访源文件双重保障 deleteOriginalAssets: false }) ] } },};这里配置完当前,临时还不能应用,还须要后端做一下配置,这里后端以nginx为例后端配置之nginx配置下方代码,间接复制粘贴应用即可 ...

June 19, 2022 · 1 min · jiezi

关于webpack:webpack打包时如何修改文件名

在应用webpack进行我的项目打包的时候,咱们可通过以下形式对不同类型的资源,进行文件名或文件门路的批改 1、应用copy-webpack-plugin插件复制的文件,这个就是配置from和to new CopyPlugin({ patterns: [ { from: "**/**.txt", to: "xx/xx.ext" }, ],})2、批改js文件的文件名在webpack中有一个output的配置项,能够在这里配置js文件的文件门路和文件名 批改入口文件的文件名通过配置output的filename属性,能够动静的扭转入口文件的文件门路和文件名,通常的咱们会这样设置filename: "[name].[chunkhash].js",而其中的name就是文件名批改的要害,这个name咱们能够在entry入口中进行定义 entry:{ index: path.resolve(__dirname, './src/index.js'), youindex: path.resolve(__dirname, './src/index.js')}在entry中也能够配置某一个库/组件的文件进行打包 entry:{ ol: path.resolve(__dirname, './static/ol/ol_me.js'),}filename除了能够设置相似占位符格局的字符串,还能够是一个函数,函数第一个参数中蕴含了打包文件的一系列信息,依据这些信息,能够去自定义打包文件的输入名称 output:{ filename: (pathData) => { return pathData.chunk.name === 'main' ? utils.assetsPath('js/youfilename.js') : utils.assetsPath('js/[name].[chunkhash].js'); }}filename占位符字符串对应的后果能够由以下参数拼接或者返回: 批改非入口(按需引入)文件的文件名通过配置output的chunkFilename 属性,能够动静的扭转非入口文件的文件门路和文件名,通常的咱们会这样设置chunkFilename: "[name].[chunkhash].js",而其中的name就是文件名批改的要害。 chunkFilename 指未被列在 entry 中,却又须要被打包进去的 chunk 文件的名称,output.chunkFilename 默认应用[id].js或从 output.filename 中推断出的值,id是输入文件的块id,个别是从1开始叠加的数字,除了[id]还能够配置占位符[name],[name]是文件按需引入时配置的chunkName值,如果没有配置chunkName,[name] 会被事后替换为 [id]。 配置好chunkFilename后,还须要在文件按需引入时配置chunkName值,晚期的按需引入应用require.ensure(),这就不说了,当初按需引入根本都是应用import(),在import()中咱们退出chunkFilename 的配置,就能够批改打包后的文件门路和文件名,配置以/* webpackChunkName: “xxx” */的模式存在 const Login = () => import(/* webpackChunkName: "myLogin" */ '../components/login.vue')在webpack 4的版本中chunkFilename必须是一个字符串,然而在webpack 5中,他也能够像filename一样设置一个函数,去自定义文件门路和文件名。 chunkFilename字符串占位符对应的后果和filename一样,能够由以下参数拼接或者返回: 3、批改css文件的文件名webpack对css文件的打包须要用到插件,之前的webpack应用extract-text-webpack-plugin进行css文件打包,这里不讲了,当初的webpack应用mini-css-extract-plugin进行css文件打包。 在mini-css-extract-plugin的配置中,同样有对于filename和chunkFilename的配置,具体用法和批改js文件名的配置一样。 const MiniCssExtractPlugin = require('mini-css-extract-plugin')new MiniCssExtractPlugin({    // Options similar to the same options in webpackOptions.output    // both options are optional    // filename: utils.assetsPath('css/[name].[contenthash].css'),    filename: (pathData) => {      return pathData.chunk.name == 'main' ? utils.assetsPath('css/youfilename.[hash].css') : utils.assetsPath('css/[name].[hash].css')    },    chunkFilename: (pathData) => {      return utils.assetsPath('css/[id].[hash].css')    },})4、批改其余资源文件(图片、视频等)的文件名webpack对图片等资源文件的打包须要用到url-loader 或者 file-loader 去正当地解决它们,而url-loader外部也是封装了file-loader去解决 ...

June 14, 2022 · 1 min · jiezi

关于webpack:webpack原理分析

loader原理loader 概念帮忙 webpack 将不同类型的文件转换为 webpack 可辨认的模块。loader 执行程序理解执行程序之前,须要先理解loader的分类 pre: 前置 loadernormal: 一般 loaderinline: 内联 loaderpost: 后置 loader 执行程序 4 类 loader 的执行优级为:pre > normal > inline > post 。雷同优先级的 loader 执行程序为:从右到左,从下到上。 // 此时loader执行程序:loader3 - loader2 - loader1module: { rules: [ { test: /\.js$/, loader: "loader1", }, { test: /\.js$/, loader: "loader2", }, { test: /\.js$/, loader: "loader3", }, ],}复制代码 // 此时loader执行程序:loader1 - loader2 - loader3module: { rules: [ { enforce: "pre", test: /.js$/, loader: "loader1", }, { // 没有enforce就是normal test: /.js$/, loader: "loader2", }, { enforce: "post", test: /.js$/, loader: "loader3", }, ],}复制代码应用 loader 的形式 ...

June 10, 2022 · 1 min · jiezi

关于webpack:Webpack一些配置介绍

装置全局装置webpack和webpack-cli,是为了能够应用webpack这个命令,不然你应用不了命令,当然手动增加环境变量也是能够的,部分装置是为了锁定版本,不便开发对立版本号,这里是应用了指定版本号的,也是踩了坑的,版本号不同,配置大同小异,然而,外面一个变动,你不晓得,出错了就有你好查的了。自己在做开发的时候,遇到的最多的就是版本号的坑。基本上webpack版本号是多少,其余的关联包,根本都要在肯定范畴内,超出了范畴,就等着一堆报错吧,自己用的这个版本是本人踩过确定可用的。 npm i webpack@4.46 webpack-cli-3.3.12 -gnpm i webpack@4.46 webpack-cli-3.3.12 -D如果不想批改一次内容,就打包一次看成果,还能够装置上面和这个包而后只须要运行,npx webpack-dev-server 或者 npx webpack serve,而后咱们再改变代码,就能立即在浏览器中看到对应的成果了npx webpack-dev-server不好记还长,那么在package.json的scripts中配置个dev启动命令吧:"dev": "webpack-dev-server" 或者 "dev": "webpack serve"该形式就是用来实时预览的,不会打包,只会在内存中虚构打包,让你看到成果,须要打包的话还是要应用webpack命令打包。 npm i webpack-dev-server@3.11.0package.json文件中的配置// 更新于2022/02/22{ "name": "webpack1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "webpack-dev-server", "build": "webpack --config webpack.config.js", "prod": "webpack --config webpack.prod.config.js" }, "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.11.6", "@babel/polyfill": "^7.11.5", "@babel/preset-env": "^7.11.5", "add-asset-html-webpack-plugin": "^5.0.1", "babel-eslint": "^10.1.0", "babel-loader": "^8.1.0", "core-js": "^3.21.1", "css-loader": "^4.3.0", "eslint": "^7.11.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-loader": "^4.0.2", "eslint-plugin-import": "^2.25.4", "file-loader": "^6.1.0", "html-loader": "^1.3.2", "html-webpack-plugin": "^4.5.0", "less": "^4.1.2", "less-loader": "^6.0.0", "mini-css-extract-plugin": "^1.0.0", "optimize-css-assets-webpack-plugin": "^5.0.4", "postcss": "^8.1.1", "postcss-loader": "^4.0.4", "postcss-preset-env": "^7.4.1", "style-loader": "^2.0.0", "url-loader": "^4.1.0", "webpack": "^4.46.0", "webpack-cli": "^3.3.12", "webpack-dev-server": "^3.11.0" }, "dependencies": { "@babel/polyfill": "^7.11.5", "core-js": "^3.21.1", "jquery": "^3.6.0" }, "browserslist": { "development": [ ">0.2%", "not dead", "not op_mini all" ], "production": [ ">0.2%", "not dead", "not op_mini all" ] }, "eslintConfig": { "extends": "airbnb-base", "parser": "babel-eslint" }}webpack.config.js配置配置中的五个外围点Entry(入口) ...

June 9, 2022 · 5 min · jiezi

关于webpack:webpack-关于chunkFilename

绝对于output.filename,output.chunkFilename用来配置通过require.ensure加载的模块文件当是cmd和amd异步加载并且没有给入口文件时,能够通过output.chunkFilename来配置命名未被列在entry中,却又须要被打包进去的文件能够通过output.chunkFilename来配置命名注:如果通过require.ensure引入的文件曾经在其余中央引入,那么就不会独自生成文件了。

June 1, 2022 · 1 min · jiezi

关于webpack:webpack-打包尚硅谷

--初始化 npm init--全局下载 webpack,webpack-cli npm i webpack webpack-cli -g--全局下载 webpack,webpack-cli npm i webpack webpack-cli -D--新建src和build目录 用来寄存代码文件及打包文件 以index.js为入口文件,打包后输出到build/build.js下开发环境:webpack ./src/index.js -o ./build/build.js --mode=development生成环境(会进行压缩):webpack ./src/index.js -o ./build/build.js --mode=production

May 29, 2022 · 1 min · jiezi

关于webpack:拍案惊奇vuecli5项目关于中的一个缓存诡异bug分析

景象形容新发了一版代码产品:“火狐没更新”我:“多刷新几次”产品:“没用”我:“强刷”产品:“好棒棒,然而你之前不是写了一个版本检测,能自动更新吗,为什么这次不论用,还要手动强刷,一般刷新不论用”我心田:"女人就是麻烦" 于是看了下复现的环境,发现了震惊的一幕HTML代码长这样我心田:绝不可能,相对不可能,啊,我的世界观崩塌了。要么全是webpakc打包的新版代码,要么走缓存全是老版代码。为啥能呈现一个html一半是新版一半是老版代码的状况??? 马桶上的思考思考过程苦思好久,没有脉络首先 有新版控制代码 Html肯定是新的然而为啥有老版代码呢 我认真有看了下本地打包后的代码,终于发现了端倪因为vue有按需加载 每个路由的css js 都是动静引入的,当初引入的是老版本的。所以这个文件应该是老版的,留神红框的文件,走的缓存,然而打包进去的还是新版的,然而因为名字没有Hash,所以获取的是缓存的文件 验证那么问题来了,vue-cli4为什么没问题呢 vue-cli-service inspect > output.js 一下能够发现 // vue-cli5 output: { filename: 'js/[name].js', chunkFilename: 'js/[name].js' }//vue-cli4 output: { filename: 'js/[name].[contenthash:8].js', }所以vue-cli5默认打包不带hash 就会造成缓存问题。而火狐的缓存问题尤为重大。必须强行清缓存。所以解决方案1.window.reload ==> window.reload(true)2.vue.config.js外面的添上 configureWebpack: { output: { filename: 'js/[name].[contenthash:8].js', }}后续上完fix版 完满解决问题产品: 棒棒哒!

May 26, 2022 · 1 min · jiezi

关于webpack:webpack5自定义插件对插入到html的js文件增加时间戳

针对js文件减少工夫戳,防止文件缓存未更新01 webpack.config.tsimport * as path from 'path';import * as webpack from 'webpack';import HelloWorld from './src/plugins/HelloWorld'; const HtmlWebpackPlugin = require('html-webpack-plugin');const config: webpack.Configuration = { entry: './src/index.ts', mode: 'development', module: { rules: [ { test: /\.(ts|tsx)$/, use: 'ts-loader', exclude: /node_modules/, } ] }, resolve: { extensions: ['ts', 'js', 'tsx'], modules: ['node_modules'], }, output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, plugins: [ new HelloWorld(), new HtmlWebpackPlugin(), ]}export default config;02 tsconfig.json{ "compilerOptions": { "outDir": "./dist/", "noImplicitAny": true, "target": "es5", "jsx": "react", "allowJs": true, }}03 src/plugins/HelloWorld.ts应用插件的自定义钩子的形式产生了变动: compilation.plugin['xxx'] -> HtmlWebpackPlugin.getHooks(compilation)alterAssetTagGroups 将行将插入html的脚本进行分组后触发的钩子寻找特定的文件:(i.attributes?.src as string)?.indexOf('bundle.js') > -1从新批改文件src:i.attributes.src = ${i.attributes.src}?${(new Date().valueOf())};import { Compiler } from "webpack";import * as HtmlWebpackPlugin from 'html-webpack-plugin';export default class HelloWorld { static defaultOptions = { outputFile: 'assets.md', } name = "HelloWorld"; options: any; constructor(options: any = {}) { this.options = { ...HelloWorld.defaultOptions, ...options, } } apply(compiler: Compiler) { const pluginName = HelloWorld.name; const { webpack } = compiler; const { Compilation } = webpack; const { RawSource } = webpack.sources; compiler.hooks.thisCompilation.tap(pluginName, (compilation) => { compilation.hooks.processAssets.tap({ name: pluginName, stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE, }, (assets) => { const content = "# In this build: \n \n" + Object.keys(assets) .map(filename => `- ${filename}`) .join('\n'); compilation.emitAsset( this.options.outputFile, new RawSource(content) ) }); }) compiler.hooks.compilation.tap(pluginName, (compilation) => { HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tap(HelloWorld.name, (config) => { // console.log(config.headTags.forEach(i => console.log(i))); config.headTags.forEach(i => { console.log((i.attributes?.src as string)?.indexOf('bundle.js') > -1); if (i.tagName === 'script' && (i.attributes?.src as string)?.indexOf('bundle.js') > -1) { i.attributes.src = `${i.attributes.src}?${(new Date().valueOf())}`; } }) return config; }) }) }}

May 13, 2022 · 2 min · jiezi

关于webpack:scss中export-无效问题

在scss中 $red:#C03639;$green: #30B08F;$yellow:#FEC171;:export { red: $red; green: $green; yellow: $yellow;}在js中 import styles from './var.scss';console.log(styles) // {red: '#C03639', green: '#30B08F', yellow: '#FEC171'}这几天学习到在js中引入scss/less变量的操作,然而本人在js中获取为空,查了很多,没有正确解决方案,肝掉不少头发后,总算找到问题:次要起因是mini-css-extract-plugin和vue-style-loader同时存在时候,会呈现这个问题,引入mini-css-extract-plugin 时候,须要去掉vue-style-loader,目前没有发现去掉vue-style-loader 后有什么问题如果间接应用vue-cli4 创立我的项目,不会存在这个问题,vue-cli 曾经做了相应解决,源码为: if (shouldExtract) { rule .use('extract-css-loader') .loader(require('mini-css-extract-plugin').loader) .options({ hmr: !isProd, publicPath: cssPublicPath })} else { rule .use('vue-style-loader') .loader(require.resolve('vue-style-loader')) .options({ sourceMap, shadowMode })}还有个 依照名称为.module.scss的能够解决的,这个是vite 打包时候无效,应用webpack 不行,具体的能够参考vite的文档css module,https://vitejs.cn/guide/featu...心愿对你有所帮忙

May 13, 2022 · 1 min · jiezi

关于webpack:webpackconfig

webpack-config一、config-path1.config-output-devserver-publicPath简述: /** * output: * - publicPath: index.html外部的援用门路 * - 域名 + (缺'/'时,浏览器会主动增加)publicPath + filename 本地拜访时(不应用dev-server),不必加域名 * - 论断:在本地拜访,写''或相对路径,应用dev-server应用''或以'/'结尾的绝对路径 * * devServer: * static: * - publicPath(之前在devServer下): 指定本地服务所在的目录(将打包的后果放在指定目录之下) * 倡议将output.publicPath 与 devServer.publicPath 保持一致 * - directory(之前在devServer下,contentPath): 咱们打包之后的资源,如果依赖其它资源,就告知去哪里找 * - watch:true 检测资源变动,主动刷新 */配置: module.exports = { ... output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', publicPath: '/lg', // 默认值为' ' }, target: 'web', devServer: { hot: true, static: { publicPath: '/lg', directory:path.resolve(__dirname,'public'), watch: true }, }}2.devServer罕用配置 devServer: { compress: true, // 将资源压缩之后,再返回给客户端展现 port: 5505, // 端口 hot: 'only', // 当某个模块谬误被纠正时,只会更新单个模块,true时会更新所有模块 open:false, // 是否主动关上浏览器 historyApiFallback: true , // 当应用前端路由申请后端时,如果路由不存在,应该应用前端路由匹配 },二、proxy代理服务解决cros跨域申请: ...

May 8, 2022 · 3 min · jiezi

关于webpack:webpack5plugin

webpack5-plugin一、意识pluginloader: 转换 特定类型 读取文件时plugin: 可做更多的事件,在打包的流程中,交叉一些操作(清理原有打包后果、css压缩、创立html模板、定义我的项目全局变量等)应用一个常见的plugin(分内置与第三方),清理原有打包后果:clean-webpack-plugin下载: yarn -D add clean-webpack-plugin在webpack.config.js中配置plugins: const { CleanWebpackPlugin } = require('clean-webpack-plugin');module.exports = { ... plugins: [ new CleanWebpackPlugin() ]}/** * 插件就是一个类,相似于: * class HelloPlugin { * contructor(){} * apply(compiler) {} * } * 须要应用模块化的形式引入,而后应用new关键字创建对象,再放入plugins数组中 */二、罕用插件应用1.html-webpack-plugin应用性能: 用于生成html模板文件装置: yarn -D add html-webpack-plugin 配置插件: const HtmlWebpackPlugin = require('html-webpack-plugin');const { DefinePlugin } = require('webpack'); //用于定义我的项目全局常量plugins: [ ... new HtmlWebpackPlugin({ title: 'html-webpack-plugin', template: './public/index.html', }), new DefinePlugin({ BASE_URL: '"./"' }) ]// 未来webpack定义常量时,会间接 const BASE_URL = ./ ,会有语法错误,须要写成 const BASE_URL = '"./"'2.Babel应用a.命令行中应用babel为什么须要 Babel? ...

May 7, 2022 · 3 min · jiezi

关于webpack:webpack5Loader

webpack5(Loader)一、webpack倒退古代Web开发"问题": 采纳模块开化开发应用新个性性进步开发效率实时监控开发过程应用热更新我的项目后果打包压缩优化应用webpack实现我的项目我的项目工程化 1.Webpack性能打包:将不同类型的资源按模块的解决进行打包动态:打包后最终产出动态资源模块:webpack反对不同标准的模块化开发(兼容多种模块导入模式)2.Webpack配置文件在我的项目根目录下,新建webpack.config.js配置文件,应用webpack命令打包时,会主动应用该配置文件打包我的项目 const path = require('path')module.exports = { entry:'./src/main.js', output:{ path:path.resolve(__dirname,'dist'), // 这里必须要配置为绝对路径 filename:'bundle.js' }}指定配置文件打包: webpack --config lg.webpack.js二、Loader应用1.cssLoader的应用未应用css-loader之前的代码: import '../css/login.css';function login() { const oH2 = document.createElement('h2'); oH2.innerHTML = '江江学前端'; oH2.className = 'title'; return oH2;}document.body.appendChild(login());css-loader 能够将文件从不同的语言 css 转换为 JavaScript装置css-loader: yarn -D add css-loader应用css-loader行内应用: import 'css-loader!../css/login.css'; // css-loader只将css解决成以后js能够辨认或解决的模块类型,不会将css文件导入进index.html中// style-loader将css插入到head中配置到配置文件中应用: const path = require('path')module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, 'dist'), // 这里必须要配置为绝对路径 filename: 'bundle.js' }, module: { rules: [ // { // test: /\.css$/, // 个别就是一个正则表达式,用来匹配文件类型 // use: [ // { // loader: 'css-loader' // } // ] // } // 简写 只应用一个loader解决 { test: /\.css$/, loader: 'css-loader' } // 简写 是、应用多个loader解决,但个别不应用参数 // { // test: /\.css$/, // use:[ // 'css-loader', // ] // } ] }}2.style-loader应用style-loader的作用:在head标签中插入一个style标签,并填入解决好的css款式下载: ...

May 5, 2022 · 4 min · jiezi

关于webpack:一个极简单的配置检测工具

Introduction前端我的项目中有多个环境的配置,在开发/测试/内测/上线各个阶段都须要手动进行配置。且此我的项目有多个子项目的接入,在Devops流程中难以对配置进行查看,因而写了一个在Webpack打包Compiler initialize阶段的环境配置查看工具。这个工具(临时)去查看各个环境下的配置文件导出的变量名称是否雷同 How to useInstallnpm i environment-config-synchroize-pluginConfigwebpack.config.js const EnvironmentConfigSynchronizePlugin = require("./EnvironmentConfigSynchronizePlugin");module.exports = { plugins: [ new EnvironmentConfigSynchronizePlugin({ path: "src/config", env: ["DEV", "SIT"], include: /.js|json|ts/ }) ]}ParametersParameter NameDescriptionTypeRemarkpathChoose the config pathString-envSupport environment listArray\<String\>-includeRegExp of fileRegExp-Githttps://github.com/madaoLi666... Todo尽管名字叫EnvironmentConfigSynchronizePlugin,然而临时只做了一个check的性能,后续会跟进一个同步的开发。

April 26, 2022 · 1 min · jiezi

关于webpack:webpack学习笔记

首先,来个官网文档对webpack的定义:webpack 是代码编译工具,有入口、进口、loader 和插件。webpack 是一个用于古代 JavaScript 应用程序的动态模块打包工具。当 webpack 解决应用程序时,它会在外部构建一个依赖图(dependency graph),此依赖图对应映射到我的项目所需的每个模块,并生成一个或多个 bundle。webpack 的外围价值就是前端源码的打包,行将前端源码中每一个文件(无论任何类型)都当做一个 pack ,而后剖析依赖,将其最终打包出线上运行的代码。 webpack 的四个外围局部: entry 规定入口文件,一个或者多个output 规定输入文件的地位loader 各个类型的转换工具plugin 打包过程中各种自定义性能的插件那么,webpack在日常工作中,是如何配置的呢? 通常状况下,webpack的配置文件在我的项目内会分为: webpack.common.jswebpack.dev.jswebpack.prod.js别离代表专用配置,开发环境配置,线上环境配置。接下来,将按这三个文件来解说如何配置,局部基础知识和要点会写在正文中,要晓得全副配置内容,倡议查看官网文档:https://www.webpackjs.com/con... webpack.common.js: const path = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')const srcPath = path.join(__dirname, '..', 'src')module.exports = { entry: path.join(srcPath, 'index.js'), //以该门路下的index.js作为构建的开始进入入口终点后, //webpack 会找出有哪些模块和库是入口终点(间接和间接)依赖的 module: { rules: [ { test: /\.js$/, loader: ['babel-loader'], //应用哪个loader来解决文件 include: srcPath, exclude: /node_modules/ //test,include,exclude都是拿来匹配哪些文件须要被loader解决的, //优先级是exclude > include > test }, { test: /\.css$/, // loader 的执行程序是:从后往前 loader: ['style-loader', 'css-loader', 'postcss-loader'] // 加了 postcss }, { test: /\.less$/, // 减少 'less-loader' ,留神程序 loader: ['style-loader', 'css-loader', 'less-loader'] } ] }, plugins: [ new HtmlWebpackPlugin({ template: path.join(srcPath, 'index.html'), filename: 'index.html' }) ]}

April 10, 2022 · 1 min · jiezi

关于webpack:聊聊-Webpack-插件系统的关键实现-Tapable

丹尼尔:蛋兄,咱们明天聊些什么呢? 蛋学生:明天就来聊下 webpack 中插件零碎实现的要害 - Tapable 丹尼尔:Tapable? 蛋学生:没错,咱们明天换种形式来聊吧,就聊你的一天 丹尼尔:我的一天? 蛋学生:首先,每个人的一天都有这么几个阶段:早上,中午,下午,早晨。用 Tapable 的形式形容是以下这个样子: const { SyncHook } = require("tapable");class Man { constructor() { this.hooks = { morningHook: new SyncHook(), noonHook: new SyncHook(), afternoonHook: new SyncHook(), nightHook: new SyncHook(), }; } startNewDay() { this.hooks.morningHook.call(); this.hooks.noonHook.call(); this.hooks.afternoonHook.call(); this.hooks.nightHook.call(); }}丹尼尔:SyncHook 是啥? 蛋学生:先不焦急,等会你就会明确的。首先你是一个人。 丹尼尔:不然呢?难道还会是禽兽吗?(`へ´) 蛋学生:(lll¬¬) 误会误会,看看代码吧 const daniel = new Man();daniel.startNewDay();丹尼尔:哦,懂了。那我的一天都筹备干些啥呢? 蛋学生:首先是早上,早上你就做了三件事:起床,刷牙,吃早餐 丹尼尔:就这?还认为有什么惊喜呢 蛋学生:我又不是讲段子的 ╮(╯▽╰)╭,我只会讲代码,来 const daniel = new Man();// MorninggetUpAction(daniel);brushTeethAction(daniel);eatBreakfastAction(daniel);daniel.startNewDay();function getUpAction(manInst) { manInst.hooks.morningHook.tap("getUp", () => console.log("Get up"));}function brushTeethAction(manInst) { manInst.hooks.morningHook.tap("brushTeeth", () => console.log("Brush Teeth"));}function eatBreakfastAction(manInst) { manInst.hooks.morningHook.tap("eatBreakfast", () => console.log("Eat breakfast") );}输入后果: ...

March 27, 2022 · 4 min · jiezi