目录
一. 前言
1. 目标
2. 搭建思路
3. 环境准备
二. 基础知识
1. 包配置安装 npm install
2. 运行项目 npm run dev
2.1 执行npm run dev
2.2 调用入口文件 webpack.dev.conf.js
2.3 build/utils.js
2.4 config/index.js
2.5 build/webpack.base.conf.js
2.6 引入文件顺序
3. 打包项目 npm run build
3.1 运行 npm run build
3.2 调用入口文件 build.js
4. 项目检查 npm run lint
三.项目搭建
以前做过多个vue的项目,每个项目都有其自己的优势,想整合下之前开发过的所有vue项目中精华的部分,也是对自己的一个总结吧。
以vue-cli为底,在其基础上搭建项目,分几大块搭建。
像node,npm之类的下载安装,请看 https://blog.csdn.net/zbl744949461/article/details/84784268,这是多版本的node,不需要的话,直接安装一个版本就行。
使用的是vue2.x搭建,怎么下载搭建个基础的架子,网上有很多前辈文章可以参考,也可看 https://blog.csdn.net/zbl744949461/article/details/90516886 的 二.搭建项目。
先用脚手架新建个项目,如下。
为了防止开发时思路错了,又找不到以前的历史记录的尴尬,在本地用svn服务器做版本管理,方便对比,关于怎么使用svn服务器,请参考 https://blog.csdn.net/zbl744949461/article/details/90516886 的 二.搭建项目→ 3版本控制。(也可用git做版本控制,或其他方式都OK,看哪个方便)
以上准备工作做完,安装包,npm install。(打包发布到服务器时,是不上传已安装完的包的,这样文件比较下,方便其他人下载,如果把包都上传了,别人下载就会很大,下的慢。包可以把项目下载到本地后自己安装)
有网络不好或者其他问题的猿友,用npm安装很慢,即使换了淘宝镜像也不行,可以用yarn安装,npm是一个包安装完再安装下一个,yarn是所有包同时进行,所以很快。使用yarn:https://blog.csdn.net/zbl744949461/article/details/110792471
npm安装5个小时,yarn安装300秒。
在搭项目架构之前,要先说下现在这个vue-cli的运作方式,明白怎样掌控这个项目。
关于vue的目录,可以看前辈的文章,很详细https://www.cnblogs.com/zhangruiqi/p/9062005.html
最先要了解的是package.json这个文件。
package.json里默认定义了项目名称、项目版本号、项目介绍、项目作者、执行命令、生产环境要安装的包、开发环境要安装的包、引擎版本、浏览器的限制要求。
package.json文件中的字段script的每一个属性都是一个自定义的脚本命令,需要通过npm来执行。
npm是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:
允许用户从npm服务器下载别人编写的第三方包到本地使用。
允许用户从npm服务器下载并安装别人编写的命令行程序到本地使用。
允许用户将自己编写的包或命令行程序上传到npm服务器供别人使用。
还有常用的 卸载模块、更新模块、搜索模块、创建模块等。
npm run 命令:npm run命令都是定义在package.json文件的scripts节点里面的,
npm run dev就是执行package.json中的scripts中的dev中的脚本,
npm run start 就是执行package.json中的scripts中的start中的脚本,也可简写 npm start
(有4个可简写的命令npm start、npm stop、npm test、npm restart)。
(npm 命令:https://www.npmjs.cn/cli/run-script/)
在这里,需要掌握4件事,包配置安装npm install,运行项目npm run dev,打包项目npm run build,项目代码检查 npm run lint
关于包配置,开发环境的包只有在开发环境用,生产环境的包在开发和生产都要用。
比如我们在开发时用的是es6语言,开发环境有一个包,作用是在打包时把es6的语言转成es5的语言,
那么打包后,在生产环境的代码是已经转成es5的代码,就不需要再转码了,所有也就不需要这个包了。
如果是像echart(做图形的)的包,就是开发和生产环境都需要,所以要放在生产环境的包配置里。
一般安装生产环境里要用的包,用命令 npm i xxx(包名) -S 或 npm install xxx(包名) --save ;往开发环境安装包 npm i xxx(包名) -D 或 npm install xxx(包名) --save-dev。
一个关于安装包的小技巧,如果已经用 npm install 安装完包了,还想安装其他的包,
如果已经知道想安装的包的版本,可以直接在package.json的 "dependencies" 或 "devDependencies"中配置好,直接运行npm install就行,
相当于npm检查了package.json中有哪些没被安装的包,又安装了下,npm install不会把所有包重新安装一遍。
npm run 是执行脚本的命令。
npm run dev 就是执行package.json 里的scripts的dev属性的脚本
webpack-dev-server是开发服务器,npm run dev 就是启动这个服务器,后面都是配置这个服务器的启动参数。
--inline :webpack-dev-serve有2种刷新模式 inline模式和iframe模式。
官方文档:https://webpack.docschina.org/configuration/dev-server/#devserverinline
2种模式的介绍: https://segmentfault.com/a/1190000014141798
inline模式 是在 bundle 中插入脚本以进行实时重新加载,并且构建消息将出现在浏览器控制台中,
iframe模式是在网页中嵌入了一个iframe
,将我们自己的应用注入到这个iframe
当中去,在通知栏下使用带有有关构建消息的
使用Iframe mode和Inline mode达到的效果都是一样的,都是监听文件的变化,然后再将编译后的文件推送到前端,完成页面的reload的,就是实时刷新,当使用HMR(热替换)功能时,推荐使用inline mode。
在 CLI 中没有方法禁用inline
--progress: 将运行进度输出到控制台。是否显示在编译时候的进度条,一般都会有,看着编译的进度,体验好一些。
--config:服务器的配置文件,是build目录下的webpack.dev.conf.js文件
--host:有一些情况,我们会改变服务器的默认localhost改为一个具体的ip,就是在dev这里写参数 --host 192.168.0.121 (写在js后)
如果将默认的localhost改成本机的ip地址,可能不能访问。将config文件夹下的index.js中,host地址改成 '0.0.0.0'
webpack-dev-server还有其他的属性,请看官方文档。
文件代码
① 代码使用严格模式 use strict
② 定义常量 utils,引入文件 build/utils.js
文件里主要定义一些工具函数。
③ 定义常量 webpack,引入webpack
打包工具
④ 定义常量 config 引入文件 config/index.js
这个文件里是项目的配置。
⑤ 定义常量 merge,引入插件 webpack-merge
merge是什么,它有什么用处?
随着我们业务逻辑的增多,图片、字体、css、ES6以及CSS预处理器和后处理器逐渐的加入到我们的项目中来,
进而导致配置文件的增多,使得配置文件书写起来比较繁琐,更严重者(书写特定文件的位置会出现错误)。
更由于项目中不同的生产环境和开发环境的配置,使得配置文件变得更加糟糕。
使用单个的配置文件会影响到任务的可重用性,随着项目需求的增长,我们必须要找到更有效地管理配置文件的方法。
管理配置文件的几种方法:
在每个环境的多个文件中维护配置,并通过--config参数将webpack指向每个文件,通过模块导入共享配置。
将配置文件推送到库,然后引用库。
将配置文件推送到工具。
维护单个配置文件的所有配置并在那里进行分支并依赖--env参数。
简单来说,配置的参数被分到各个文件中,如果配置文件被分成了许多不同的部分,那么必须以某种方式来组合他们,通常就是合并数组和对象,webpack-merge很好的做到了这一点。
webpack-merge做了两件事:它允许连接数组并合并对象,而不是覆盖组合。
https://www.cnblogs.com/cczlovexw/p/11765571.html
⑥ 定义常量 path,引入nodejs路径模块
path是node的path,path 模块提供了一些工具函数,用于处理文件与目录的路径。
https://www.nodeapp.cn/path.html
⑦ 定义常量 baseWebpackConfig,引入文件 build/webpack.base.conf.js
这里引入了一个公共的配置:const baseWebpackConfig = require('./webpack.base.conf')
为什么会单独抽离一个公共配置:主要是因为在打生产包和平时调试的一些相同的配置能够一起使用,然后有差异的地方,通过对象合并的方式,后面的覆盖前面的,然后达到每个环境私有化配置的目的。
⑧ 定义常量 CopyWebpackPlugin,引入插件 copy-webpack-plugin
这个插件的作用是在webpack中拷贝,将单个文件或整个目录复制到构建目录,拷贝文件和文件夹。
比如打包项目时,js文件和css文件会被合并,图片不用合并,直接复制到打包的项目目录下就好了。这个包就是起这个复制作用。
参数:
from 定义要拷贝的源文件 from:__dirname+'/src/components'
to 定义要拷贝到的目标文件夹 to: __dirname+'/dist'
toType file 或者 dir 可选,默认是文件
force 强制覆盖前面的插件 可选,默认是文件
context 可选,默认base context可用specific context
flatten 只拷贝指定的文件 可以用模糊匹配
ignore 忽略拷贝指定的文件 可以模糊匹配
用法:
const CopyWebpackPlugin=require('copy-webpack-plugin');
new CopyWebpackPlugin([
{
from: __dirname+'/src/components',
to: __dirname+'/dist',
ignore: ['.*']
}
])
⑨ 定义常量 HtmlWebpackPlugin,引入插件 html-webpack-plugin
html-webpack-plugin 插件是用于编译 Webpack 项目中的 html 类型的文件,简单来说,就是一个用于生成HTML文件并自动注入依赖文件(link/script)的webpack插件。
如果直接将 html 文件置于 ./src 目录中,用 Webpack 打包时是不会编译到生产环境中的。
因为 Webpack 编译任何文件都需要基于配置文件先行配置的
简单来说html-webpack-plugin就是生成一个html文件,可以是无配置的,无配置的情况它可以自动生成一个html,如下
是把默认bundle.js引入的,但是很多情况下我们的index.html可能有一些特殊的内容,这样默认的配置不能满足,
这时候html-webpack-plugin的配置项就会起作用,最经常使用的就是 template:'你的html的路径'。
参数:
title: 用来生成页面的 title 元素
filename: 输出的 HTML 文件名,默认是 index.html, 也可以直接配置带有子目录。
template: 模板文件路径,支持加载器,比如 html!./index.html
inject: true | 'head' | 'body' | false ,注入所有的资源到特定的 template 或者 templateContent 中,如果设置为 true 或者 body,所有的 javascript 资源将被放置到 body 元素的底部,'head' 将放置到 head 元素中。
favicon: 添加特定的 favicon 路径到输出的 HTML 文件中。
minify: {} | false , 传递 html-minifier 选项给 minify 输出
hash: true | false, 如果为 true, 将添加一个唯一的 webpack 编译 hash 到所有包含的脚本和 CSS 文件,对于解除 cache 很有用。
cache: true | false,如果为 true, 这是默认值,仅仅在文件修改之后才会发布文件。
showErrors: true | false, 如果为 true, 这是默认值,错误信息会写入到 HTML 页面中
chunks: 允许只添加某些块 (比如,仅仅 unit test 块)
chunksSortMode: 允许控制块在添加到页面之前的排序方式,支持的值:'none' | 'default' | {function}-default:'auto'
excludeChunks: 允许跳过某些块,(比如,跳过单元测试的块)
⑩ 定义常量 FriendlyErrorsPlugin,引入插件 friendly-errors-webpack-plugin
友好的错误提示插件,Friendly-errors-webpack-plugin识别某些类别的webpack错误,并清理,聚合和优先级,以提供更好的开发人员体验。
从webpack错误中提取相关信息。 这是通过这里的插件完成的
将变换器应用于所有错误,以识别和注释众所周知的错误并为其提供优先级
如果没有抛出错误,则仅获取最高优先级错误或最高优先级警告
将格式化程序应用于所有带注释的错误
⑪ 定义常量 portfinder,引入portfinder
portfinder帮你自动获取可用端口,当设置的端口被占用,自动寻找下一个。(循环,当前端口+1,直到找到可用为止)
参数:
port: 3000, // minimum port
stopPort: 3333 // maximum port
⑫ 定义常量 HOST
const HOST = process.env.HOST
process
对象是一个 global
(全局变量),提供有关信息,控制当前 Node.js
进程。作为一个对象,它对于 Node.js
应用程序始终是可用的,故无需使用 require()
。
process是node的当前进程对象,process.env属性会返回包含用户环境的对象
就是这个 env
属性,在 development
和production
不同环境上,配置会有些不同。
process.env.HOST就是当前环境的HOST
在新建的项目,还没配置HOST,控制台打印,显示undefined(启动项目时,webstorm的程序控制台中,不是网页console里打印)
有兴趣可以打印下process.env试试
⑬ 定义常量 PORT
当前环境的端口
⑭ 定义常量 devWebpackConfig
这个常量的目的是,将webpack的基础配置(webpack.base.conf.js中导出的对象)和一些其他配置合并。
⑮ 导出
导出一个异步操作的最终完成 (或失败)及webpack的配置。
这个文件最终目的是返回一个webpack的配置。
这个文件里主要定义一些工具函数。
文件代码
① 代码使用严格模式 use strict
② 定义常量 path,引入nodejs路径模块
path是node的path,path 模块提供了一些工具函数,用于处理文件与目录的路径。
https://www.nodeapp.cn/path.html
③ 定义常量 config 引入文件 config/index.js
这个文件里是项目的配置。
④ 定义常量 ExtractTextPlugin,引入插件 extract-text-webpack-plugin
webpack的打包机制:webpack本来只能打包处理.js文件,但是通过强大的loader之后,可以打包处理各种类型的文件。比如:.css文件
但css的内容都被打包到bundle.js里面,为了将css模块和js模块分开打包,使用这个插件。
https://blog.csdn.net/weixin_41134409/article/details/88416356
⑤ 定义常量 packageConfig 引入文件 package.json
⑥ 导出函数 assetsPath
函数目的:执行函数,返回当前环境下的静态资源目录与自己目录 的合并目录。
执行过程:
判断当前环境是不是生产,如果是,用build的静态资源存放路径,不是,就用dev的静态资源存放路径。(在config/index.js中)
path.posix是path的一个方法,用于处理posix样式的目录(posix的目录用的是/,相对的win32目录中用的是\)
https://blog.csdn.net/u014711690/article/details/111639640
http://nodejs.cn/api/path.html#path_path_posix
assetsSubDirectory是除了 index.html 之外的静态资源要存放的路径(在config/index.js中)
⑦ 导出函数 cssLoaders
函数目的:设置css加载器属性,不同css语言的用不同的加载器解析使用。
⑧ 导出函数 styleLoaders
函数目的:为独立样式文件生成加载程序(除.vue之外)
⑨ 导出函数 createNotifierCallback
函数目的:创建通知程序回调,返回提示。
执行过程:引入node的notifier模块,用于处理所有应用程序级别的通知(苹果推送通知,邮件和Facebook帖子)
没报错,返回空,报错,返回具体格式的错误提示。
这个文件里是项目的一些配置。
dev(本地测试环境)和build(生产环境)的一些配置。
① 测试环境配置
assetsSubDirectory:除了 index.html 之外的静态资源要存放的路径,简称静态资源文件夹
assetsPublicPath:代表打包后,index.html里面引用资源的的相对地址
proxyTable:定义开发服务器的代理规则。需要 proxyTable 代理的接口(可跨域)
host:主机地址
post:运行测试页面的端口
autoOpenBrowser:运行后项目是否自启,设置true就会自动打开浏览器,运行项目。
errorOverlay:查询错误
notifyOnErrors:通知错误
poll:与devserver相关的一个配置,webpack提供的devserver是可以监控文件改动的,但在有些情况下却不能工作,我们可以设置一个轮询(poll)来解决
useEslint:是否使用eslint,在用vue-cli搭建项目的时候,有询问
showEslintErrorsInOverlay:是否展示eslint的错误提示
devtool:webpack提供的用来方便调试的配置,它有四种模式:
1 source-map :产生一个单独的source-map文件,功能最完全,但会减慢打包速度
2 eval-source-map :使用eval打包源文件模块,直接在源文件中写入干净完整的source-map,不影响构建速度,但影响执行速度和安全,建议开发环境中使用,生产阶段不要使用
3 cheap-module-source-map:会产生一个不带映射到列的单独的map文件,开发者工具就只能看到行,但无法对应到具体的列(符号),对调试不便
4 cheap-module-eval-source-map:不会产生单独的map文件,(与eval-source-map类似)但开发者工具就只能看到行,但无法对应到具体的列(符号),对调试不便
默认设置的第四种 https://zhuanlan.zhihu.com/p/265266279
cacheBusting:一个配合devtool的配置,当给文件名插入新的hash导致清楚缓存时是否生成souce maps,默认在开发环境下为true
cssSourceMap:是否开启cssSourceMap
② 生产环境配置
index:编译后index.html的路径,path.resolve(__dirname, '../dist')中
path.resolve(__dirname)指的是index.js所在的绝对路径,再去找“../dist”这个路径(node相关的知识),
必须是本地文件系统上的绝对路径。
assetsRoot:打包后的文件根路径,至于assetsSubDirectory和assetsPublicPath跟dev中的一样,必须是本地文件系统上的绝对路径。
assetsSubDirectory:打包前静态资源存放目录?
assetsPublicPath: 代表打包后,index.html里面引用资源的的相对地址
这个是通过http服务器运行的url路径。在大多数情况下,这个是根目录(/)。如果你的后台框架对静态资源url前缀要求,你仅需要改变这个参数。
在内部,这个是被webpack当做output.publicPath来处理的。
后台有要求的话一般要加上./ 或者根据具体目录添加,不然引用不到静态资源
productionSourceMap:是否开启source-map,
devtool:同dev,
productionGzip:是否压缩,
productionGzipExtensions:gzip模式下需要压缩的文件的扩展名,设置后会对相应扩展名的文件进行压缩
bundleAnalyzerReport: 是否开启打包后的分析报告
前辈使用地址经验,如图:
文件代码:
① 严格模式
② 引入nodejs路径模块
③ 引入文件 build/utils.js
里面有一些工具函数
④ 引入文件 config/index.js
这个文件里是项目的配置。
⑤ 引入文件 build/vue-loader.conf.js
vue-loader.conf配置文件是用来解决各种css文件的,定义了诸如css,less,sass之类的和样式有关的loader
判断是不是生产环境,根据环境来获取相应的productionSourceMap或者cssSourceMap
导出
module.exports = {
loaders:utils.cssLoaders({
sourceMap:sourceMapEnabled, //是否开始sourceMap 用来调试
extract:isProduction //是否单独提取抽离css ,是否将单独的css文件(一般为引入的外部文件)进行提取单独打包
}),
cssSourceMap:sourceMapEnabled, //记录压缩的代码,用来找到源码位置
cacheBusting:config.dev.cacheBusting, //是否缓存破坏
transformToRequire:{ //作用是在模块编译的过程中,编译器可以将某些属性,比如src转换为require调用
video:['src','poster'],
source:'src',
img:'src',
image:'xlink:href'
}
}
⑥ resolve函数用来获取路径的
__dirname是当前文件(webpack.base.conf.js)的路径,用join拼接'..'得到项目路径,再去拼接所需路径,返回的就是所需目录完整的路径。
⑦ 定义常量createLintingRule
这常量是在vue开启了语法检查时会用的,没开就不会用到。
test: /\.(js|vue)$/
loader: 'eslint-loader', //对.js和.vue文件在编译之前进行检测,检查有没有语法错误
enforce: 'pre', // 让eslint插件能够在编译之前检测,如果不添加此项,就要把这个配置项放到末尾,确保第一个执行
include: [resolve('src'), resolve('test')], // 指明这些目录下的文件要被eslint-loader检测,还有一个exclude表示排除某些文件夹
options: { // options表示传递给eslint-loader的参数
formatter: require('eslint-friendly-formatter') // eslint-friendly-formatter是eslint的一个报告总结插件,eslint的检测报告非常难看懂,这个插件就是整理这些报告方便查阅的
emitWarning: !config.dev.showEslintErrorsInOverlay
}
⑧ 导出webpack的基本配置
context:项目路径
entry:入口文件配置
入口文件是src目录下的main.js
output:出口文件配置
path: config目录下的index.js中的build配置中的assetsRoot,默认是dist目录 (没改的话),可以被后续的文件配置合并覆盖掉
filename:文件名称这里使用默认的name也就是main
publicPath:上线地址,也就是真正的文件引用路径,如果是production生产环境,这里是 '/'
resolve:
extensions:是用来对模块的后缀进行解析,省略扩展名。
例:引入模块 require('../config') ,webpack.base里引入了config模块的时候,没有带js后缀,文件本质上是不会识别的,
有了这个配置,会先进行.js后缀匹配,没匹配成功,再匹配.vue,没有再匹配 .json,最后都没有找到就会报错,文件没有找到no find。
alias:配置别名,起到简化路径的作用
vue$: $符号指精确匹配,相当于 import vuejs from "vue"就是导入vue.esm.js文件
@:当你需要在一个很深的文件引入其他文件中又一个很深的文件, 要写很长的相对路径,
别名可以设定一个入口位置,比如用@来代替src目录的绝对路径,如果开发的所有文件都放在src目录下,就可以通过src目录直接定位到你想要找的文件。
这样再引入文件时,就可以写成 import HelloWorld from '@/components/HelloWorld'
module:解析不同模块的配置
是否设置了代码检查,设置了就加入代码检查规则。
属性说明:
test:是用来解析所有test中设置的.xxx后缀的文件,这里分别对.vue、.js、图片、音视频、字体文件进行解析
loader:用什么npm什么形式的loader去解析这些文件
在解析js文件时,用的是babel-loader解析器,进行es6转换成es5的,但不是所有js文件都解析,在node_modules中很多都转好了,直接用,而且
include:代表解析的文件中包含那些东西,比如需要解析的文件的目录。
options:是对解析文件参数配置
vueLoaderConfig 是对vue文件的style样式进行解析,解析编译,再进行ExtractTextPlugin来进行合并
limit:10000:将低于limit设置的图片(或音频,或字体文件等)进行base64编码,以减少http请求,就是让8kb之内的图片编码,大于8kb的图片如果编码会太长,所以用http请求加载。
(将图片文件转换为base64编码并载入浏览器能够减少http请求数,但是增大了js或html文件的体积,如果图片在项目中的重用度较高,那么每处引用都会生成base64编码,造成了代码的冗余。通过http请求载入到浏览器的文件可以缓存到本地,当图片在项目中的重用度较高时,会为图片的访问增加缓存的便利性,下次访问更快。因此要平衡考虑)
name : 对输出的内容地行地址转换,一个图在dev开发的时候用../../xx/xx.jpg, 到生产环境地址要重新生成唯一的地址,为了清缓存时用,此时就要用到地址转换。
'img/[name].[hash:7].[ext]':就是生成img目录下,原文件名+7位的hash值+文件原来的后缀
node: 以下选项是Node.js全局变量或模块,这里主要是防止webpack注入一些Node.js的东西到vue中
所有,npm run dev 这个命令执行的文件顺序是:(←:前引入后)
bulid/webpack.dev.conf.js ← build/utils.js ← config/index.js
← config/index.js
← build/webpack.base.conf.js ← build/utils.js
← config/index.js
← build/vue-loader.conf ← build/utils.js
← config/index.js
← src/main.js
如下图:
执行打包时, npm run build相当于执行package.json中的scripts中的build属性的脚本,就是执行node build/build.js
build.js说明:https://blog.csdn.net/xiaoxiaoluckylucky/article/details/85863819
文件代码
① 代码使用严格模式 use strict
② 引入文件 build/check-versions.js,用于检查版本
③ 设置当前全局环境是生产环境
④ 定义常量 ora 引入插件 ora
⑤ 定义常量 rm,引入插件 rimraf
⑥ 定义常量 path,引入nodejs路径模块
(同npm run dev)
⑦ 定义常量 chalk,引入插件 chalk
⑧ 定义常量 webpack,引入webpack
(同npm run dev)
⑨ 定义常量 config 引入文件 config/index.js
(同npm run dev)
⑩ 定义常量 webpackConfig 引入文件 build/webpack.prod.conf.js
⑪ 定义常量 spinner
⑫ spinner启动
⑬ rm
文件代码
流程图:
eslint:http://eslint.cn/docs/user-guide/getting-started
https://www.cnblogs.com/hahazexia/p/6393212.html
1.环境准备
项目自带本地测试和生产环境,一般项目都会有3个环境,那我们需要再加一个服务器测试环境的配置。
这篇文章写的有些长了,不方便大家浏览,这里新开一个文章,以方便大家阅读。(持续更新中。。。)
https://blog.csdn.net/zbl744949461/article/details/117593089