在从零学习vue之简单演练——构建单页面项目中,我对vue脚手架的架构做了一个很简单的分析。
在这篇文章中,将会深入学习vue架构和webpack和服务端的配置问题。
主要参考了官方文档,这里对官方文档进行了说明以及翻译。
1.项目架构
build/
存储了开发服务器的配置(node)、生成webpack配置文件,通常情况下不需要改变这些文件,除非需要自己定制Webpack loaders,在这种情况下可以看/webpack.base.conf.js
config/index.js
这是主要的配置文件,提供最常用的构建配置接口。
src/
这里是项目代码主要存储的地方,这里的结构目录主要取决于开发者。
static/
这个目录是用于存储静态资源,放在这里的文件不会被webpack打包。他们会被原封不动地复制到webpack构建出来的对应相同目录下。
test/unit
包含单元测试相关文件。
test/e2e
包含e2e测试相关文件。
index.html
这是单页面项目的模板index.html,在开发构建过程中,webpack会生成assets资源,对应的URL会自动插入至这个模板中并渲染。
package.json
NPM配置元文件,包含构建依赖、选项参数等。
2.构建命令
所有的构建命令都是通过NPM Scripts实现的。
npm run dev
(开启一个Node.js开发服务器)
- Webpack + vue-loader对于单页面组件.
- 保持热加载状态
- 保持编译错误重叠状态
- ESLint
- SourceMaps
npm run build
(构建assets资源用于生产)
- 使用UglifyJS压缩JS
- html-minifier压缩HTML
- 所有组件内的CSS压缩成单个文件并使用cssnano压缩
- 所有为保存长期缓存而包含版本哈希号编译的静态assets资源,以及自动集成这些资源URL的index.html
npm run unit
(使用Karma运行单元测试)
- 支持ES2015+
- 支持所有的webpack loaders
- 简单的mock inkection
npm run e2e
(使用Nightwatch运行端到端测试)
3.Linter配置
使用ESlint作为linter,采用标准预设置,并做了一些小的定制化。
如果你不喜欢默认的linting规则,可以有几种选择:
- 在.selintrc.js中重写个人规则。例如,你可以新增一下规则强制使用分号而不是忽略他们:
"semi": [2, "always"]
- 集成项目时,选择一个不同的ESlint预设值。
- 集成项目时,选择"none"作为ESLint预设值,这样自己定义规则。
4.预处理器
可采用现在非常流行的几种预处理器:LESS、SASS、Stylus和PostCSS。如果采用预处理器,所要做的就是安装合适的webpack loader。例如,采用SASS:
npm install sass-loader node-sass --save-dev
注意需要安装node-sass因为sass-loader是依赖于它的。
在组件中使用预处理器
一旦安装了,你就可以在*.vue组件中使用预处理器了,所做的只需要在<style>标签中添加lang属性:
<style lang="scss">
/* write SASS! */
</style>
SASS语法说明
- lang="scss"代表CSS-superset语法(使用大括号和分号)
- lang="sass"代表缩紧格式语法
PostCSS
*.vue文件中的样式默认传入PostCSS中的,因此不需要使用一个特定的loader。可以简单增加你所想使用的PostCSS插件在下列位置:
// build/webpack.base.conf.js
module.exports = {
// ...
vue: {
postcss: [/* your plugins */]
}
}
独立的CSS文件
为了确保可靠的提取和处理,建议在App.vue中引用全局、独立的文件。例如:
<!-- App.vue -->
<style src="./styles/global.less" lang="less"></style>
你可能仅仅应该针对你自己编写的样式来做如上处理。对于那些现有的库,例如Bootstrap或者Semanic UI,你可以把他们放置在/static下,然直接在index.html中引入。这避免额外的构建时间,也可以更好地被浏览器缓存。
5.处理静态Assets资源
你可能注意到了项目结构中有两个静态assets资源:src/assets和static/,这两者有什么区别呢?
Webpacked Assets
为了回答这个问题,我们需要先理解Webpack是怎样处理static assets的。在*.vue组件中,所有模板templates和CSS是通过vue-html-loader和css-loader解析的并找到对应assets URL的。例如,在background: url(./logo.png),"./logo.png"是一个相对的assets路径,会被webpack作为模块依赖进行重定向。
因为logo.png不是JavaScript,当作为一个模块依赖时,我们需要使用url-loader和file-loader来处理。样板项目中已经配置了这些loaders,因此诸如fingerprinting文件命名法和满足条件下的base64等基本的功能在相对路径下都可以使用,而不必担心配置问题。
由于这些assets可能会在构建过程中被inlined/copied/renamed,他们作为你的源代码中的必要的一部分。这就是为什么建议要将会被webpack处理的assets放置于/src,以区分其他源文件。实际上,你甚至没有必要把他们放在/src/assets中,你可以口模块/组件组织并使用他们。例如,你可以把每个组件放在它单独的目录下,包含它自己的静态assets文件。
Asset重定向规则
- 相对URL,如./assets/logo.png会被解释成一个模块依赖。他们会被替换为一个自动生成URL,依据你的Webpack输出配置。
- 无前缀URL,如assets/logo.png ,与./assets/logo.png相同
- 以~为前缀的URL 会被作为模块请求对待,类似于require('somemodule/image.png),如果想利用webpack的模块重定向配置,你需要使用这个前缀。例如你拥有一个assets重定向别名,你需要使用~assets/logo.png来确保别名被接受。
- 根路径相对URL,例如/assets/logo.png 不会被做任何处理。
在JS中获取Assets路径
为Webpack返回正确的asset路径,你需要使用equire('./relative/path/to/file.jpg'),这将会被file-loader处理,并返回重定向URL,例如
computed: {
background () {
return require('./bgs/' + this.id + '.jpg')
}
}
注意以上的例子将会包含./bgs/下的每一个图片。因为Webpack无法猜测他们中的哪一个是在使用中的,因此会包含所有。
"Real" Static Assets
相比较而言,static/下的文件不会被Webpack处理。他们直接拷贝至最终目录,包括相同的文件名。你引用这些文件必须使用绝对路径,在config.js中的build.assetsPublicPath、build.assetsSubDirectory。
以下有个例子:
// config.js
module.exports = {
// ...
build: {
assetsPublicPath: '/',
assetsSubDirectory: 'static'
}
}
static/目录下的每一个文件被引用时,必须采用绝对URL /static/[filename],如果你更改了assetSubDirectory为assets,那么这些URL需要更改为assets/[filename]。
6.环境变量
有时候根据项目所处环境配置不同变量是很使用的。
例子:
// config/prod.env.js
module.exports = {
NODE_ENV: '"production"',
DEBUG_MODE: false,
API_KEY: '"..."' // this is shared between all environments
}
// config/dev.env.js
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
DEBUG_MODE: true // this overrides the DEBUG_MODE value of prod.env
})
// config/test.env.js
module.exports = merge(devEnv, {
NODE_ENV: '"testing"'
})
注意:string变量需要被单引号和双引号包裹'"..."'
因此,环境变量是:
- Production
- NODE_ENV = 'production',
- DEBUG_MODE = false,
- API_KEY = '...'
- Development
- NODE_ENV = 'development',
- DEBUG_MODE = true,
- API_KEY = '...'
- Testing
- NODE_ENV = 'testing',
- DEBUG_MODE = true,
- API_KEY = '...'
使用
使用环境变量很简单,如:
Vue.config.debug = process.env.DEBUG_MODE
7.与后端框架集成
如果你在构建纯静态app(与后端部署分离),那么你可能不需要编辑config/index.js。但是如果你想与一个已经存在的后端框架集成这个模板,例如Rails/Django/Laravel,使用他们自己的工程框架,那么你可以编辑config/index.js来生成front-end assets到后端工程。
(这一章及以后的代理、测试等章节,我尚且没有用到,暂时不做翻译了就~偷个懒先)