最近想學一門前端框架,之前看了一些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
最后的文件目錄是這樣的
下面就開始分析這些目錄中的這些文件
首先要說的是
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文件夾
這個文件夾里的文件是和編譯相關的