彻底解析Vue2 webpack脚手架文件目录
最近想学一门前端框架,之前看了一些Angular1的教程,难学就不说了,它的主人好像有了放弃他的意思,推出了Angular2,基本上算是推翻了重来,而且文档还要越过GFW才能看,最近特别火的React也不错,但是最后还是选了文档十分友好的Vue,它借鉴了Angular1的指令和React组件化思想,在2.0版本中还加入了virtual DOM。
这是一个渐进式框架,不同于jquery的直接操作dom,它是数据驱动的,Vue 的核心库只关注视图层,是一个轻量级的框架,可以和其他库相整合。废话不多说,大家可以去这个网站去看它的详细文档。
实践才能真正掌握它,vue可以像jquery一样通过<script>
标签的方式写到html中,现在前端技术日新月异,在我看来,如果现在学习的话还不用新的东西,还要学老一套的,迟早要被淘汰,这里我使用的是vue-cli,使用webpack来搭建这个项目,对于webpack的介绍请看这里,总之它非常好用,也是我要学习它的原因,这个脚手架工具,这有vue-cli的安装方法,当然最简单的方法就是从github上直接copy下来,这里是连接,下载下来后在解压后的文件夹内安装依赖
$ npm install
最后的文件目录是这样的
vue 示例下面就开始分析这些目录中的这些文件
首先要说的是
package.json
这个文件,这是整个文件的灵魂啊,
{
"name": "example",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "xxx",
"private": true,
"scripts": {
"dev": "node build/dev-server.js",
"build": "node build/build.js",
"lint": "eslint --ext .js,.vue src"
},
"dependencies": {
//真的依赖。。
"vue": "^2.0.1"
},
"devDependencies": {
//太多省略了
//这里是开发时的依赖
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
}
}
这个文件是可以通过npm init
控制行命令生成,前提是你电脑得装了node,如果没有的话,这篇文章可以先不用看了,先去装个node吧。
package.json
这个文件是json格式的文件,它的每一个键值对,储存了这个项目的数据, "dependencies"
和"devDependencies"
是这个项目所要用到的依赖包,什么是依赖包呢,就拿就jquery和bootstrap说吧,要想使用bootstrap就要先引入jquery,而这就产生了依赖关系,webpack可以将所要用到的各种资源文件包括js、css等文件打包,好处就是将繁杂的资源引用打包,减少http请求数,压缩资源存储空间,加快网页访问速度。
回到这个文件,"dependencies"
主要是网页所要用到的依赖包,我们演示的是vue示例,当然就有"vue": "^2.0.1"
这一条了,后面的是依赖包的版本号;而"devDependencies"
是开发时的包依赖,比如我们要想在js配置文件中使用es6的语法就需要引用barbel依赖,要模拟服务器就要使用express模块等等,但是他们只是开发的时候用,资源打包编译过后就不用这些组件或模块了,因此写在"devDependencies"
下边。
node是一个js的运行环境,npm是随着node一起安装的包管理工具,正确装完node之后就可以使用命令行指令了,通过node指令可以执行js文件
$ node xx.js //执行某文件
而npm指令可以执行package.json
里定义的相关操作
"scripts": {
"dev": "node build/dev-server.js",
"build": "node build/build.js",
"lint": "eslint --ext .js,.vue src"
},
$ npm installl
//把dependencies和devDependencies中的依赖下载安装到node_modules文件夹
$ npm run-script dev
//也可以这么写
$ npm run dev
//执行package.json中的dev这个指令,在这里等同于
$ node build/dev-server.js
//这里可以自己随便写,引号里的是要在命令行执行的指令
打开文件夹,在这个文件下打开命令行,shift
+鼠标右键打开命令行
我们执行
$ npm run dev
这样就成功的在浏览器中显示了
可是对这个过程是怎么实现的依然一头雾水
那我们就从这个指令开始吧$ npm run dev
,之前说了,这个指令就是执行这个目录build/下的dev-server.js文件
build文件夹
build文件目录是这样的
|-build
|-build.js
|-check-versions.js
|-dev-client.js
|-dev-server.js
|-utils.js
|-webpack.base.conf.js
|-webpack.dev.conf.js
|-webpack.prod.conf.js
(瞬间感觉压力巨大,但是本着不能轻言放弃的原则,我会坚持下去的)
打开dev-server.js
这个文件,有点大,如果你能一条条读下来,相信会收获很多的
require('./check-versions')()
//这里是将package.json中的engine要求的node,npm版本号和本地版本相比对
//如果不符合就会在命令行用红色和绿色的文字发出警告
var config = require('../config')
//引入另一个文件夹config的index.js总之是一些配置组成的对象
if (!process.env.NODE_ENV) process.env.NODE_ENV = config.dev.env
//process是nodejs中的一个全局对象,可以看作一个进程,这个procee.env中保存着当前shell的环境变量
//这里是如果这个环境变量中没有NODE_ENV这个属性,就将它的值设为开发模式development,相对的还有生产模式production
var path = require('path')
//这是node里的自带模块,用来处理相对路径绝对路径等
var express = require('express')
//这是一个基于nodejs的开发框架,可以搭建开发环境下的服务器
var webpack = require('webpack')
//资源打包模块
var opn = require('opn')
//一个用来打开网页、文件、可执行文件的模块
var proxyMiddleware = require('http-proxy-middleware')
//服务器中间件,匹配对应请求的的URL地址, 匹配的请求将被代理到目标主机
var webpackConfig = require('./webpack.dev.conf')
//在大型项目中,可能 webpack.config.js 会变得越来越臃肿,这个时候可以
//利用做 webpack-merge 插件。将配置定义在一个目录下面的不同文件中
//然后通过 webpack-merge 来合并成最终的配置。
var port = process.env.PORT || config.dev.port
// 设置端口号
var proxyTable = config.dev.proxyTable
//代理表,可以将复杂的url简写
var app = express()
//实例化一个express
var compiler = webpack(webpackConfig)
//实例化一个compiler
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
stats: {
colors: true,
chunks: false
}
})
var hotMiddleware = require('webpack-hot-middleware')(compiler)
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
hotMiddleware.publish({ action: 'reload' })
cb()
})
})
// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
var options = proxyTable[context]
if (typeof options === 'string') {
options = { target: options }
}
app.use(proxyMiddleware(context, options))
})
// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())
// serve webpack bundle output
app.use(devMiddleware)
// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)
// serve pure static assets
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))
module.exports = app.listen(port, function (err) {
if (err) {
console.log(err)
return
}
var uri = 'http://localhost:' + port
console.log('Listening at ' + uri + '\n')
// when env is testing, don't need open it
if (process.env.NODE_ENV !== 'testing') {
opn(uri)
}
})
打开build.js
这个文件
// https://github.com/shelljs/shelljs
require('./check-versions')()
//这里是将package.json中的engine要求的node,npm版本号和本地版本相比对,如果不符合就会在命令行用红色和绿色的文字发出警告
require('shelljs/global')
//可以在js文件中使用unix命令,比如mkdir、rm、cp
env.NODE_ENV = 'production'
//这个是设置生产环境的标志
var path = require('path')
//node自带模块,用来处理路径
var config = require('../config')
//配置信息
var ora = require('ora')
//命令行工具
var webpack = require('webpack')
var webpackConfig = require('./webpack.prod.conf')
//载入webpack的配置文件
console.log(
' Tip:\n' +
' Built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
)
//命令行提示文字
var spinner = ora('building for production...')
spinner.start()
var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory)
rm('-rf', assetsPath)
mkdir('-p', assetsPath)
cp('-R', 'static/*', assetsPath)
//文件操作,创建目录文件
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n')
})
//这里webpack将产生打包文件,webpack这个函数会根据配置文件生成匹配的打包文件
//这个回调函数将结果输出在控制台上
build文件夹
这个文件夹里的文件是和编译相关的