webpack构建流程(基础篇——webpack基础用法(三))
本文目录
- 基础篇——webpack基础用法(三)
- Webpack打包流程细节源码解析(P2)
- webpack打包的CSS含有两个相同的引入
- 前端构建工具Gulp.js 你知多少..(webpack/gulp/grunt)
- vue项目完整搭建步骤
- webpack编写插件
- webpack执行机制流程是怎么样的
- webpack到底怎么用
- webpack打包原理
- vue2.0用脚手架搭建的官方例子怎么用webpack打包 如何配置
基础篇——webpack基础用法(三)
上一章节主要介绍了 entry 、 output 、 loa**rs 、 plugins 、 mo** 等核心概念以及简单的使用方法的介绍,接下来主要介绍文件的解析、压缩、热更新原理等。
安装url-loa**r
npm install url-loa**r -D
上图是自己写的**mo,在search.js中引用图片资源,此示例为未使用url-loa**r时文件大小 134kb ;
上一节中讲解了 webpack文件** 可以实现文件的自动构建,但是每次必须手动刷新浏览器,那么有没有不用每次手动刷新浏览器,自动构建文件呢?答案是肯定的, 热更新 。
注意:WDS因为是放在内存中,而watch是有对系统进行文件的输出,所以在构建速度上WDS也是明显快于watch的
接下来我们实际操作一下:
在package.json中添加一个**v命令,配置好webpack-**v-server;
npm i webpack-**v-server -D
修改webpack.config.js中的 mo** 为 **velopment ,因为 production 是生产环境下使用的,而 **velopment 是开发环境下使用的,所以在使用WDS的情况下,要将mo**修改为 **velopment ;
配置 HotModuleReplacementPlugin 插件和 **vServer ,因为HotModuleReplacementPlugin是webpack内置插件,所以不用额外安装的。
注:通常适用express、koa等后端服务,需要引用no**js
注:一般js用Chunhash,css用Contenthash
到这里 webpack基础篇 已经讲完了,下一章节开始 webpack进阶篇
Webpack打包流程细节源码解析(P2)
此篇博客紧承上一篇,上片讨论了我们的webpack整个处理单个文件的流程,这一节主要说一说webpack的文件打包问题,其实本身是比较简单的,但是有异步块和html-plugin的加入,使这个步骤变得尤为复杂,这里先介绍几个重要的概念:
上一节中,我们成功的对每个文件进行了处理,并通过了process的方法对所有入口文件以及他们的依赖文件进行了处理,获得了最初的依赖文件列表,现在我们就可以对资源的依赖进行优化处理,本片的内容将从webpack/lib/Compiler.js:510的断点开始逐步的对源码进行分析
在seal之前,由于一轮***pilition已经执行完成,先调用finish方法进行收尾处理与之对应的是我们注册的finish-modules事件,
这里我们首先看到的又是in**x.ejs这个老朋友,由于他是单独的文件经过了loa**r处理没有获得额外的处理函数的依赖,所以最终这里看到的module实际上是它的js外壳包起来的ejs文件,此阶段也还没有进行资源hash的注入等等
这里有一个FlagDepen**ncyExportsPlugin进行了操作,听名字可能就听出来了,他是对我们资源中的export使用进行一个标志的作用, 和我们最终做出的tree shaking效果可能是相关的
调用seal事件处理
处理我们的preparedChunk,这个东西是我们刚好在进行addEntry的时候添加上的不知道你们还记不记得,中途就没有添加过新的,所以讲道理,一个entry是只用一个的,但是这里使用了一个数组不知道有什么用意
然后把这个入口模块添加到了block里面,过后打包也是从block里面拿数据,block里面的东西会被打包成为单独的文件,但是还是工作在之前的上下文中,这里可以通过看一下这里的import即是我们之前在路由文件中通过import函数设置引入的动态加载路由资源
进入到processDepen**nciesBlockForChunk函数,就开始处理我们之前做好准备的block了,这里这是一个不断处理依赖的过程,但是没有使用递归的做法,毕竟文件太多了,不断的进行递归会浪费很多空间,取而代之的是使用queue进行记录,处理过程中不断把新的需要处理的模块放到queue里面等待下一步处理
在每一步的处理中
处理完这一波循环依赖过后,本身的依赖树结构变得扁平化,之前一层一层的模块通过**pen**ncy连接起来作为一个树的结构,而现在变成了顶层最终的几个chunk
可以看到我们最终在这个入口(entry)设置中拿到了9个chunk,她们都有_modules属性,我们的所有依赖都是放到这里面的,是用的一个Set进行存储,其中的依赖关系则是通过origins和reason等标识进行模块间关系的连接的
还可以将我们的入口chunk和异步加载的chunk进行一些对比(上面的是入口文件),下面的chunk中出现的origins就是指向我们之前的router那个module
这个图里也可以看到,两个chunk实际上按照自己的路子搜集了所有的依赖,结果导致了_modules的文件数量都达到了一千多个,这就是我们常使用的CommonChunk插件需要处理的地方了,稍后进行讨论
这轮处理我们成功的把主要的入口module和异步加载的模块区分开了,然后开始按照类似的逻辑处理我们的第一个入口模块
这个时候拿到chunkDepen**ncies进行处理,这就是之前那个存储block的东西,但是有个很奇怪的地方,就是这里面居然只有三个chunk,而不是和上面的一样是9个也不是只有一个入口模块,这就让人无从下手了(我异步加载的模块并不是一样的,而且这些模块之间没有没相互依赖)
喜闻乐见进行第二次处理,首先取出一个chunk拿到对应的存储在value中的**ps,对每一个项目添加上了他们的parent,但是有个组件就是用来removeParent的
在RemoveParentModulesPlugin这个插件中,针对每个module都做了处理,看看这些模块在哪些chunk之中有被使用到,把他们所存在的chunks按照id记录下来,并改变她们的reason为几种统一的chunk组合数组。这样就做到了每个module知道了自己被哪些chunk使用,但是从之前的单一reason到现在的多reason具体不知道有什么用(恩。。可能是为作用域提升做准备)
然后嘛,移除空的模块,不需要多解释
然后这层处理就算完啦,主要进行了模块的依赖梳理和拆分,并为他们添加上了指向父节点的指针(话说之前不是有origins吗)
对模块进行排序工作,不过只是按照索引进行排序罢了,那个按照出现概率进行排序处理的插件不是在这里工作的
又是那个flag的插件进行了处理,但是只是把所有模块的used设置为了true,还有为一些被依赖的module设置上他们的usedExports为true
ChunkConditi***插件用于监视模块上是否有chunkCondition函数,并返回他的执行结果,如果有模块的此函数返回了false,那么将会重写这个模块(重写即是重新添加进入parent的链接以及reason等的设置)并且还会返回true,到至此过程不断执行直至condition全部OK
RemoveParentModulesPlugin这个插件的作用有点玄乎,看样子是对每个chunk进行处理,看对于多个chunk中都有的某一些module,会直接把他们的reason设置为主要的入口chunk,而后把当前chunk中的module移除掉(话说这个事情不是应该Common来做吗)
然后移除所有空的模块,再就是移除重复的模块了(话说一直用set神他妈还会有重复的)
然后进行各种优化,比如出现的概率大的放到前面,这里还是做了module和chunk两种优化,也是有毛病,就像我们的react项目中可以知道react的使用次数最多,那么他就被放到了最钱前面,紧随其后的是echart等
HashedModuleIdsPlugin插件为我们的模块计算出它的id,默认是通过md5进行计算,解出来的是base64的,而且计算的参数也仅仅只是通过模块的libId进行hash,而这个libhash只是相对位置,连绝对的都不是,所以算下来这个东西能够当成单个文件的hash了
applyModuleId,到这里你可能会想,诶之前不是已经设置好每个元素的id了吗,为什么还要搞这么个函数专门处理,我们在上一个生成id的时候实际上得到的id是根据我们的设置进行了截断的,实际上拿到的hash碰撞的概率非常大,我们看看下面这个筛选的处理就可以知道,1885个模块里面竟然又3个重复的id,这种时候就要特殊处理了
执行sortItemsWithModuleIds依据id进行排序,不只是最外面的chunk,就连reason里的id也会被重新排序,也是蛮逗的,这里直接用的是id做比较并没有判断类型,也就是说把数字和字符串会混到一起,就算你是class也会拿valueOf出来比较,想想还是蛮刺激的,不过其实比较完成也没有太特殊的用途就这么随意一点也好
中间一些处理recordId的我忽略掉了
然后开始处理hash了,这里的hash具体使用了哪些参数和长度是多少呢
可以在此阶段添加hashSalt即噪声,给hash值添加一些特征
进入mainTemplate的处理函数中,添加了一些字符串参数和数字参数,并且调用了mainTemplate的hash插件,但是她们的执行过程并不是保证我们最后生成的文件中能够有结果的hash值,便于请求对应的资源文件,而是仅仅在hash的过程中添加了一些干扰的路径参数等
最终一轮hash下来,chunk会得到自己的ren**rHash,而***pilation会得到一个针对编译过程的hash,这个hash就跟我们的所有资源扯上关联啦,所以每次都是新的
创建模块资源咯~
这些文章写的都有点水,相当于是阅读源码时候做的笔记了,看看图个乐子吧
webpack打包的CSS含有两个相同的引入
1. 摘要
Webpack是一种前端资源构建工具,一个静态模块打包器。在Webpack看来,前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理,当Webpack处理应用程序时,它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源。Webpack打包流程图如图1-1所示。
想了解Webpack,看这篇就够了
图1-1 Webpack打包流程图
2. Webpack五个核心概念
2.1 Entry
入口(Entry)指示Webpack以哪个文件作为入口起点分析构建内部依赖图并进行打包。
2.2 Output
输出(Output)指示Webpack打包后的资源bundles输出到哪里去,以及如何命名。
2.3 Loa**r
Loa**r让Webpack能够去处理那些非JavaScript语言的文件,Webpack本身只能理解JavaScript。
2.4 Plugins
插件(Plugins)可以用于执行范围更广的任务,插件的范围包括从打包和压缩,一直到重新定义环境中的变量等。
2.5 Mo**
模式(Mo**)指示Webpack使用相应模式的配置。分为**velopment和production两种模式,下面分别进行简述。
**velopment: 开发模式,能让代码本地运行的环境,会将process.env.NODE_ENV的值设为**velopment,同时启用NamedChunksPlugin和NamedModulesPlugin插件;
production: 生产模式,能让代码优化运行的环境,会将process.env.NODE_ENV的值设为production,同时启用FlagDepen**ncyUsagePlugin、FlagInclu**dChunksPlugin、ModuleConcatenationPlugin、NoEmitreplaceStringsPlugin、OccurrenceOr**rPlugin、Si**EffectsFlagPlugin和UglifyJsPlugin插件。
3. Wbepack配置
3.1 webpack.config.js文件
webpack.config.js是webpack的配置文件,用来指示webpack工作,运行webpack指令时,会加载里面的配置,所有构建工具都是基于no**js平台运行的,默认采用***monjs模块化。webpack.config.js基础配置如图3-1所示。
想了解Webpack,看这篇就够了
图3-1 webpack.config.js基础配置
3.2 **vServer配置
开发服务器(**vServer)用来实现自动化(自动编译、自动打开浏览器、自动刷新浏览器),只会在内存中编译打包,不会有任何文件输出,本地安装webpack-**v-server后,通过npx webpack-**v-server命令启动**vServer,核心代码如图3-2所示。
想了解Webpack,看这篇就够了
图3-2 **vServer配置核心代码
3.3 打包html/样式/图片/其它资源
打包不同的资源会使用不同的loa**r和插件,打包html/样式/图片/其它资源的流程如下所述。
3.3.1 打包html资源
1.下载html-webpack-plugin插件;
2.引入html-webpack-plugin插件;
3.使用html-webpack-plugin插件,并进行相应配置。
3.3.2 打包样式资源
不同的样式文件需要配置不同的loa**r
1.下载loa**r;
2.配置loa**r,css样式文件使用css-loa**r和style-loa**r,less文件使用less-loa**r、css-loa**r和style-loa**r。其中css-loa**r的作用是将css文件变成***monjs模块加载到js文件中,style-loa**r的作用是创建style标签,将js中的样式资源插入进去,添加到head中生效。
3.3.3 打包图片资源
1.下载url-loa**r,file-loa**r
2.配置loa**r
3.3.4 打包其它资源
1.下载file-loa**r
2. 配置loa**r,配置该loa**r作用于不为html/css/less/js的其他文件
3.4 提取css成单独文件/css兼容性处理/压缩css
3.4.1 提取css成单独文件
样式文件打包后会默认和js文件一起输出,可以通过插件将打包后的css文件单独输出,流程如下所述。
1.下载mini-css-extract-plugin插件
2.引用该插件
3.配置
3.4.2 css兼容性处理
1.下载postcss-loa**r和postcss-preset-env
2.在package.json中browsetslist属性中分别对开发环境和生产环境进行兼容性配置,设置支持样式的浏览器版本
3.通过postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式。
3.4.3 压缩css
1.下载optimize-css-assets-webpack-plugin插件
2.引用该插件
3.使用该插件
3.5 js语法检查esl***/js兼容性处理/js压缩
3.5.1 js语法检查esl***
1.下载esl***-loa**r和esl***
2.在package.json中的esl***Config中进行配置
3.配置esl***-loa**r,其中只需检测js文件并要排除第三方库,只检测自己写的源代码,同时可在opti***配置中设置fix:true,自动修复esl***的错误。
3.5.2 js兼容性处理
1.下载babel-loa**r、@babel/core、@babel/preset-env,通过@babel/preset-env做基本的js兼容性处理,然后通过corejs做前面无法实现的兼容性处理,并实现按需加载
2. 配置loa**r
js兼容性处理核心代码如图3-3所示
想了解Webpack,看这篇就够了
图3-3 js兼容性处理核心代码
3.5.3 js压缩
mo**设置为production生产环境时会自动压缩js代码。
4. webpack性能优化
可以从开发环境和生产环境分别对webpack进行性能优化。其中开发环境主要考虑从打包构建速度和代码调试两个方面进行优化,生产环境主要考虑从打包构建速度和代码运行性能这两个方面进行优化。下面简单介绍下开发环境上通过HMR提升构建速度。
4.1 HMR
HMR(热模块替换),作用是一个模块发生变化后,只会更新打包这一个模块而不是所有模块,通过在**vServer中设置hot:true属性启动HMR功能。
其中对于样式文件,可以使用HMR功能,因为style-loa**r内部实现了;
对于js文件,默认不能使用HMR功能,解决方法:修改入口文件js代码,添加支持HMR功能的代码,另外HMR只能处理非入口js文件的其他文件,对入口文件并不能生效,因为一旦入口文件更新,入口文件引入的其他文件一定会被重新加载;
对于html文件,默认不能使用HMR功能,同时会导致html文件不能热更新,解决方法:修改entry入口文件,将html文件引入,只能解决html文件不能热更新的问题。
前端构建工具Gulp.js 你知多少..(webpack/gulp/grunt)
@ TOC
阅读本文章之前,相信你已经对前端构建工具(webpack、gulp、grunt)有一定的认知和了解了,那么他们之间究竟有什么区别呢?
gulp文档上面有这么一句话 ,也就是说 gulp是一个自动化构建工具;
gulp的一些功能如下(包括但不限于):
其实Webpack和另外两个并没有太多的可比性
傻瓜式起步照搬官网文档
1.安装
2.在项目根目录下创建一个名为 gulpfile.js 的文件:
3.运行 gulp:
默认的名为 **fault 的任务(task)将会被运行,在这里,这个任务并未做任何事情。
具体详情可以查看 gulpjs.***文档
新建一个项目gulp-test
环境:
1.新建文件以下文件如下
其中 gulpfile.js 是我们gulp的配置文件,启动gulp默认会找个这个文件并执行;
2.接下来安装依赖
一直按回车Enter初始化package.json文件(小技巧: npm iniy -y 可以免去繁琐的enter步骤)
此时我们的目录结构是这样了
安装依赖
这里页面实时刷新只讲这个 gulp-connect ,其他详情可以参照 Browsersync 和文章 gulp-livereload
安装完依赖后配置gulpfile.js如下:
大概讲解一下gulpfile.js:
gulp.task 是gulp的api 定义一个使用 Orchestrator 实现的任务(task)
如上我们定义了 my-task-js , my-task-css , html , clean , **fault , watch , server 等任务,其中:
my-task-js 是将 符合所提供的匹配模式的js 进行检测(gulp-jsh***)、压缩(gulp-uglify)、合并(gulp-concat)、重命名(gulp-rename)、输出(gulp.**st)到/dist/js目录下;
my-task-css 是将 符合所提供的匹配模式的sass进行编译(gulp-sass)、压缩(gulp-uglify)、合并(gulp-concat)、重命名(gulp-rename)、输出(gulp.**st)到/dist/css目录下;
html 是将 符合所提供的匹配模式的html进行**,如果有变化则connect.reload()
clean 是如果任务重新启动时 删除旧文件;
**fault gulp默认启动的任务
watch gulp的api 监视文件,并且可以在文件发生改动时候做一些事情。它总会返回一个 EventEmitter 来发射(emit) change 事件。
server 依赖gulp-connect启动一个服务器
配置完gulpfile.js之后,我们给js和css及html加点东西:
首先js/helloworld.js
css/in**x.scss
in**x.html
运行gulp
浏览器效果:
接下来我们修改helloworld.js来看看是否能实时刷新
修改如下:
按保存之后,终端给我们报了一个错:
查看js发现我们用了es6语法的声明语句 但当前gulp无法处理es6语法,有问题解决问题,es6=》es5
解决方案:
安装gulp-babel babel-core babel-preset-es2015
gulpfile.js修改如下:
运行
依然报上面的错;找了一些原因发现,虽然安装了相关依赖,却没有配置.babelrc文件,即babel还没转化es6
根目录添加.babelrc文件
重新运行:
查看dist下的js文件
改变helloworld.js检查页面是否刷新
保存,页面的天空蓝换成你们喜欢的yellow颜色
修改in**x.scss 查看是否会刷新页面
最后修改in**x.html 查看是否会刷新页面
今天主要学习了gulp的简单项目搭建及实时更新配置;其实gulp类似于grunt的弱化版,但更简单好用,只是插件会少一些,目前主流的项目搭建工具主要是webpack,但依然有不少项目还用着gulp或者grunt
扩展:
下面还有一些楼主的学习笔记:
有兴趣的可以多多交流@ 楼主博客
vue项目完整搭建步骤
为了让一些不太清楚搭建前端项目的小白,更快上手。今天我将一步一步带领你们进行前端项目的搭建。前端开发中需要用到框架,那vue作为三大框架主流之一,在工作中很常用。所以就以vue为例。
下载并安装no**
***隐藏网址***
在 no**js官网下载最新版稳定版的no**.js安装,自带了npm工具 ,推荐下载左边的。
检查no**是否安装成功
***隐藏网址***
在终端输入以下命令:
检测**pm是否安装成功
vue-cli是vue脚手架工具,方便打包,部署,测试等。
进入你的项目目录,创建一个基于 webpack 模板的新项目: vue init webpack 项目名
进入项目
安装依赖
此时项目中会多了一个no**_modules
启动成功
webpack编写插件
查看原文 | 此页
插件向第三方开发者提供了 webpack 引擎中完整的能力。使用阶段式的构建回调,开发者可以引入它们自己的行为到 webpack 构建流程中。创建插件比创建 loa**r 更加高级,因为你将需要理解一些 webpack 底层的内部特性来做相应的钩子,所以做好阅读一些源码的准备!
webpack 插件由以下组成:
在插件开发中最重要的两个资源就是 ***piler 和 ***pilation 对象。理解它们的角色是扩展 webpack 引擎重要的第一步。
这两个组件是任何 webpack 插件不可或缺的部分(特别是 ***pilation ),因此,开发者在阅读源码,并熟悉它们之后,会感到获益匪浅:
插件是由「具有 apply 方法的 prototype 对象」所实例化出来的。这个 apply 方法在安装插件时,会被 webpack ***piler 调用一次。 apply 方法可以接收一个 webpack ***piler 对象的引用,从而可以在回调函数中访问到 ***piler 对象。一个简单的插件结构如下:
然后,要安装这个插件,只需要在你的 webpack 配置的 plugin 数组中添加一个实例:
使用 ***piler 对象时,你可以绑定提供了编译 ***pilation 引用的回调函数,然后拿到每次新的 ***pilation 对象。这些 ***pilation 对象提供了一些钩子函数,来钩入到构建流程的很多步骤中。
关于 ***piler , ***pilation 的可用回调,和其它重要的对象的更多信息,请查看 插件 文档。
有一些编译插件中的步骤是异步的,这样就需要额外传入一个 callback 回调函数,并且在插件运行结束时, 必须 调用这个回调函数。
一旦能我们深入理解 webpack ***piler 和每个独立的 ***pilation,我们依赖 webpack 引擎将有无限多的事可以做。我们可以重新格式化已有的文件,创建衍生的文件,或者制作全新的生成文件。
让我们来写一个简单的示例插件,生成一个叫做 filelist.md 的新文件;文件内容是所有构建生成的文件的列表。这个插件大概像下面这样:
webpack 插件可以按照它所注册的事件分成不同的类型。每一个事件钩子决定了它该如何应用插件的注册。
applyPlugins(name: string, args: any...)
applyPluginsBailResult(name: string, args: any...)
这意味着每个插件回调,都会被特定的 args 一个接一个地调用。 这是插件的最基本形式。许多有用的事件(例如 "***pile" , "this-***pilation" ),预期插件会同步执行。
applyPluginsWate***ll(name: string, init: any, args: any...)
这种类型,每个插件都在其他插件依次调用之后调用,前一个插件调用的返回值,作为参数传入后一个插件。这类插件必须考虑其执行顺序。 必须等前一个插件执行后,才能接收参数。第一个插件的值是 初始值(init) 。这个模式用在与 webpack 模板相关的 Tapable 实例中(例如 ModuleTemplate , ChunkTemplate 等)。
applyPluginsAsync(name: string, args: any..., callback: (err?: Error) -》 void)
这种类型,插件处理函数在调用时,会传入所有的参数和一个签名为 (err?: Error) -》 void 的回调函数。处理函数按注册时的顺序调用。在调用完所有处理程序后,才会调用 callback 。 这也是 "emit" , "run" 等事件的常用模式。
applyPluginsAsyncWate***ll(name: string, init: any, callback: (err: Error, result: any) -》 void)
这种类型,插件处理函数在调用时,会传入当前值(current value)和一个带有签名为 (err: Error, nextValue: any) -》 void. 的回调函数。当调用的 nextValue 是下一个处理函数的当前值(current value)时,第一个处理程序的当前值是 init 。在调用完所有处理函数之后,才会调用 callback,并将最后一个值传入。如果其中任何一个处理函数传入一个 err 值,则会调用此 callback 并将此 error 对象传入,并且不再调用其他处理函数。 这种插件模式适用于像 "before-resolve" 和 "after-resolve" 这样的事件。
applyPluginsAsyncSeries(name: string, args: any..., callback: (err: Error, result: any) -》 void)
- 并行(parallel) -
applyPluginsParallel(name: string, args: any..., callback: (err?: Error) -》 void)
applyPluginsParallelBailResult(name: string, args: any..., callback: (err: Error, result: any) -》 void)
webpack执行机制流程是怎么样的
几乎所有业务的开发构建都会用到 webpack 。的确,作为模块加载和打包神器,只需配置几个文件,加载各种 loa**r 就可以享受无痛流程化开发。但对于 webpack 这样一个复杂度较高的插件集合,它的整体流程及思想对我们来说还是很透明的。那么接下来我会带你了解 webpack 这样一个构建黑盒,首先来谈谈它的流程。 准备工作 1. webstorm 中配置 webpack-webstorm-**bugger-script 在开始了解之前,必须要能对 webpack 整个流程进行 **bug ,配置过程比较简单。 先将 webpack-webstorm-**bugger-script 中的软件外包企业公司 置于 webpack.config.js 的同一目录下,搭建好你的脚手架后就可以直接 Debug 这个 webstorm-**bugger.js 文件了。 2. webpack.config.js 配置 估计大家对 webpack.config.js 的配置也尝试过不少次了,这里就大致对这个配置文件进行个分析。 var path = require(’path’); var no**_modules = path.resolve(__dirname, ’no**_modules’); var pathToReact = path.resolve(no**_modules, ’react/dist/react.min.js’); module.exports = { // 入口文件,是模块构建的起点,同时每一个入口文件对应最后生成的一个 chunk。 entry: { bundle: ; } ... // 与当前模块构建步骤相同 } 3. 构建细节 module 是 webpack 构建的核心实体,也是所有 module的 父类,它有几种不同子类:NormalModule , MultiModule ,ContextModule , DelegatedModule 等。但这些核心实体都是在构建中都会去调用对应方法,也就是 build() 。来看看其中具体做了什么: // 初始化module信息,如context,id,chunks,**pen**ncies等。 NormalModule.prototype.build = function build(opti***, ***pilation, resolver, fs, callback) { this.buildTimestamp = new Date().getTime(); // 构建计时 this.built = true; return this.doBuild(opti***, ***pilation, resolver, fs, function(err) { // 指定模块引用,不经acorn解析 if(opti***.module && opti***.module.noParse) { if(Array.isArray(opti***.module.noParse)) { if(opti***.module.noParse.some(function(regExp) { return typeof regExp === "string" ? this.request.in**xOf(regExp) === 0 : regExp.test(this.request); }, this)) return callback(); } else if(typeof opti***.module.noParse === "string" ? this.request.in**xOf(opti***.module.noParse) === 0 : opti***.module.noParse.test(this.request)) { return callback(); } } // 由acorn解析生成ast try { this.parser.parse(this._source.source(), { current: this, module: this, ***pilation: ***pilation, opti***: opti*** }); } catch(e) { var source = this._source.source(); this._source = null; return callback(new ModuleParseError(this, source, e)); } return callback(); }.bind(this)); }; 对于每一个 module ,它都会有这样一个构建方法。当然,它还包括了从构建到输出的一系列的有关 module 生命周期的函数
webpack到底怎么用
30分钟手把手教你学webpack实战
首先对于很多刚接触webpack人来说,肯定会问webpack是什么?它有什么优点?我们为什么要使用它?带着这些问题,我们来总结下如下:
Webpack是前端一个工具,可以让各个模块进行加载,预处理,再进行打包,它能有Grunt或Gulp所有基本功能。优点如下:
支持***monJS和AMD模块。
支持很多模块加载器的调用,可以使模块加载器灵活定制,比如babel-loa**r加载器,该加载器能使我们使用ES6的语法来编写代码。
可以通过配置打包成多个文件,有效的利用浏览器的缓存功能提升性能。
使用模块加载器,可以支持sass,less等处理器进行打包且支持静态资源样式及图片进行打包。
更多等等。。。带着这些问题我们慢慢来学习webpack。
***隐藏网址***
webpack打包原理
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(**pen**ncy graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle
webpack.config.js里配置
webpack.config.js里配置
webpack loa**r 将所有类型的文件,转换为应用程序的依赖图可以直接引用的模块
通过require()将想要使用的插件添加到plugins数组中,多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。
npm init -y
安装webpack
npm i webpack_dome webpack-cli -D
在根目录下新建src文件夹,在src里新建in**x.js文件
in**x.js文件
创建并配置webpack.config.js文件
webpack.config.js文件
配置 package.json 文件,在scripts中添加’build’使得运行 npm run build 可以直接执行 webpack 命令,在根目录内会生成dist文件夹,里面是对应生成的文件,
安装 npm install --save-**v express webpack-**v-middleware ,添加’start’使得运行 npm run start 可以直接执行 webpack-**v-server 命令,
package.json 文件
再次打包时需要删除旧文件
执行 npm install clean-webpack-plugin --save-**v 命令,安装依赖。
修改webpack.config.js文件配置
新建in**x.html文件,并手动引入打包后的js文件
执行 npm i html-webpack-plugin --save-**v 命令,安装依赖。
新建in**x.ejs文件
修改webpack.config.js文件配置
重新运行 npm run build,生成新的 dist 包,包内会生成一个新的 in**x.html 文件,并自动引入了 in**x.min.js 文件。
执行 npm i open-browser-webpack-plugin webpack-**v-server --save-**v 命令,安装依赖。
修改 webpack.config.js 配置
修改webpack.config.js文件配置
vue2.0用脚手架搭建的官方例子怎么用webpack打包 如何配置
前言 vue2 然后通过以下命令安装 webpack **pm install webpack -g 注:下面 orange 默认给出 npm 的安装方案,安装失败请自行转为 **pm 安装 在需要创建工程的位置运行 vue init webpack-****** 工程名字《工程名字不能用中文》 或者创建 vue1.0 的项目,只需将命令换成 vue init webpack-******#1.0 这里我们基于 2.x 开发的,直接使用第一种方法创建工程即可,下图是创建工程时的截图,需要你添加 Project name,Project **scription,Author. 图中已经给出下一步应该操作的步骤,我们按照步骤一步一步执行,这里 orange 不给大家一步一步列出。 注意:这里一定要使用 npm install 安装官方库,而不要使用淘宝镜像,会导致部分依赖丢失。 安装完成后,目录如下图。 然后我们运行我们的项目后浏览器会自动弹出,并展示以下页面 这里注意观察,默认给我们八个链接,可以根据这几个链接获得我们想要的学习资源,上面是必要的的链接(官方文档以及关注 vue 动态),下面是 vue 的生态系统,大家亲切的叫它们为全家桶。 二、Vue 全家桶 我们接下来介绍全家桶的安装(使用详情大家可以去初始页面的链接查看) 一句命令搞定全家桶 npm install vue-router vue-resource vuex --save package.json 已经加入了我们的全家桶,no**_modules 目录下也有对应的依赖包,注意这里现在还不能用扩展之后的方法,因为我们没引入到项目中来。 src/main.js 修改如下 import Vue from ’vue’ import VueResource from ’vue-resource’ import VueRouter from ’vue-router’ import Vuex from ’vuex’ import App from ’./App.vue’ Vue.use(VueResource) Vue.use(VueRouter) Vue.use(Vuex) new Vue({ el: ’#app’, ren**r: h =》 h(App) }) 这时我们的项目就能运行对应的扩展方法了 三、集成 Sass 作为移动端的开发怎么能缺少 css 预编译语言。sass 安装需要几个依赖。 我们干脆在 package.json 把版本写死,然后通过 npm install 安装 在 "**vDepen**ncies": {} 中添加下面几个依赖 "no**-sass": "^3.8.0", "sass": "^0.5.0", "sass-loa**r": "^4.0.0", 好,我们 npm install 后,就可以正式使用 sass 啦 四、目录结构建议 依赖的安装到这里差不多结束了,其它大家需要的可以自定义安装 下面给出我的目录建议供大家参考, 这里的 img 目录放置图片,script 目录放置公共的工具函数,style 目录放置我们的 sass 文件, 你查看 App.vue 文件时不难发现,默认的把样式文件给到了模块里,这样样式一直跟着模块 orange 建议大家不要这样做,因为这样十分不利于样式的模块化,注意区分与模版模块化的区别, 我们单独设置 style 目录,并在目录当中对 sass 进行模块化处理(通过 import 引入 sass 模块) 对应的 App.vue 也变得非常简洁,代码如下 《style lang="sass"》 @import "/style/base.scss"; 《/style》 五、rem 适配 对于移动端的开发,rem 适配必不可少,我们可以用多种方式实现,下面给出一种方案 在 in**x.html 中添加如下代码 《script》 let html = document.documentElement; window.rem = html.getBoundingClientRect().width / 16 ; html.style.fontSize = window.rem + ’px’; 《/script》 这里基于宽 320px 的屏幕分成了 16 份,也就是 1rem = 20px,目前大多数设计稿都是根据 iphone6 的宽( 375px )走的,建议大家在这里分成 25 份,也就是 1rem = 15px,计算起来方便些。 简单说下 rem 原理:根据 html 的 fontSize 属性值为基准,其它所有的 rem 值,根据这个基准计算。 我们根据屏幕宽度用 js 动态修改了 html 的 fontSize 属性值,达到移动端适配的目的 总结 以上就是这篇文章的全部内容了,本文作为移动端配置的基础篇,深入了解框架后才能继续构建网站,希望这是一个好的开始,有了这个架子再填充代码就方便了许多,不用再去考虑开发环境问题了。希望本文的内容对有需要的朋友们能有所帮助。
更多文章:
plsqlupdate语句(oracle 中plsql 怎样写更新一行的语句)
2026年4月21日 18:00
管理系统的设计与实现(【企业信息化管理平台的设计与实现】 华为企业信息化管理)
2026年4月21日 17:40
matlab中画图命令(如何用matlab直接画图-matlab如何描点画图)
2026年4月21日 17:20
webpack构建流程(基础篇——webpack基础用法(三))
2026年4月21日 16:40
宝马service灯(宝马530li仪表显示service如何消除)
2026年4月21日 16:20
sql server怎么导出数据库文件(sqlserver怎么导出数据库)
2026年4月21日 16:00
sqlserver2000客户端(高手来看,sql server 2000客户端连接不上服务器)
2026年4月21日 15:40
excel函数mid用法(使用MID函数在excel中提取指定字符)
2026年4月21日 15:20
associate editor(副总编 用英语怎么写~~~~急)
2026年4月21日 15:00

