1.下載vue-cli
npm install vue-cli -g
vue-cli的使用與詳細介紹,可以到github上獲取https://github.com/vuejs/vue-cli
2.安裝webpack項目模版
vue init <template-name> <project-name>
例如:
vue init webpack my-project
根據(jù)提示進去項目文件、安裝依賴
cd my-project
npm install
npm run dev
安裝所有的依賴包鸥拧,可以得到如下的目錄結(jié)構(gòu)
20170119201547551.png
3.目錄結(jié)構(gòu)與文件配置說明
首先對目錄結(jié)構(gòu)進行說明,
1.build目錄削解,主要利用webpack與node插件啟動一些相關(guān)服務(wù)的js文件
2.config目錄主要是針對開發(fā)環(huán)境富弦,生產(chǎn)環(huán)境,測試環(huán)境的配置信息
3.src是我們自己開發(fā)時的源碼目錄(可指定修改名稱)
4.static是一些第三方庫的包用到的靜態(tài)資源目錄(可指定修改名稱)
說明每個文件:
主要入口文件氛驮,dev-server.js文件腕柜,幾乎每一句話都進行了注釋,有些地方柳爽,涉及了其他關(guān)聯(lián)文件媳握,下面也會有相應(yīng)的注釋的方式
// 引入檢查版本js模塊
require('./check-versions')()
// 引入配置文件信息模塊
var config = require('../config')
// 判斷開發(fā)環(huán)境
if (!process.env.NODE_ENV) process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
// 引入nodejs的path模塊碱屁,進行一些路徑的操作磷脯,詳情可以查看node官方的api
var path = require('path')
// 引入nodejs的一個框架express,可以幫助我們快速搭建一個node服務(wù) github https://github.com/expressjs/express
var express = require('express')
// 引入node為webpack提供的一個模塊服務(wù) github https://github.com/webpack/webpack
var webpack = require('webpack')
// 可以指定打開指定的url使用指定的瀏覽器或者應(yīng)用,詳情可以去看一下github https://github.com/sindresorhus/opn
var opn = require('opn')
// 一個可以設(shè)置幫助我們進行服務(wù)器轉(zhuǎn)發(fā)代理的中間件 https://github.com/chimurai/http-proxy-middleware
var proxyMiddleware = require('http-proxy-middleware')
// 根據(jù)當前啟動環(huán)境選擇加載相應(yīng)的配置文件娩脾,webpack.prod.conf與webpack.dev.conf文件的說明后面也有
var webpackConfig = process.env.NODE_ENV === 'testing'
? require('./webpack.prod.conf')
: require('./webpack.dev.conf')
// 端口號的設(shè)置
var port = process.env.PORT || config.dev.port
// 獲取需要代理的服務(wù)api
// https://github.com/chimurai/http-proxy-middleware
var proxyTable = config.dev.proxyTable
// 啟動一個express服務(wù)
var app = express()
// 加載webpack配置
var compiler = webpack(webpackConfig)
// webpack的開發(fā)中間件赵誓,專門為webpack提供的一個簡單的中間件,可以讓文件都加載內(nèi)存中柿赊,不去讀寫硬盤俩功,并且當文件被改動的時候,不會刷新頁面就會部署成功
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: true
})
// 一個為webpack提供的熱部署中間件碰声。https://github.com/glenjamin/webpack-hot-middleware
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
log: () => {}
})
// 當html被改變的時候诡蜓,讓html被強制部署,使用這個中間件html-webpack-plugin胰挑,https://github.com/ampedandwired/html-webpack-plugin
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
hotMiddleware.publish({ action: 'reload' })
cb()
})
})
// 遍歷代理的配置信息,并且使用中間件加載進去
Object.keys(proxyTable).forEach(function (context) {
var options = proxyTable[context]
if (typeof options === 'string') {
options = { target: options }
}
app.use(proxyMiddleware(context, options))
})
// 當訪問找不到的頁面的時候蔓罚,該中間件指定了一個默認的頁面返回https://github.com/bripkens/connect-history-api-fallback
app.use(require('connect-history-api-fallback')())
// 使用中間件
app.use(devMiddleware)
// 熱部署
app.use(hotMiddleware)
// 根據(jù)配置信息拼接一個目錄路徑,然后將該路徑下的文件交給express的靜態(tài)目錄管理
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))
var uri = 'http://localhost:' + port
devMiddleware.waitUntilValid(function () {
console.log('> Listening at ' + uri + '\n')
})
// 導(dǎo)出的對象
module.exports = app.listen(port, function (err) {
if (err) {
console.log(err)
return
}
// when env is testing, don't need open it
if (process.env.NODE_ENV !== 'testing') {
opn(uri)
}
})
webpack.base.conf.js
var path = require('path')
var config = require('../config')
// 工具類瞻颂,下面會用到
var utils = require('./utils')
// 工程目錄豺谈,就是當前目錄build的上一層目錄
var projectRoot = path.resolve(__dirname, '../')
var env = process.env.NODE_ENV
// 是否在開發(fā)環(huán)境中使用cssSourceMap,默認是false,該配置信息在config目錄下的index.js中可以查看
var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap)
var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap)
var useCssSourceMap = cssSourceMapDev || cssSourceMapProd
// 導(dǎo)出的對象,就是webpack的配置項贡这,詳情可以參考的webpack的配置說明茬末,這里會將出現(xiàn)的都一一說明一下
module.exports = {
// 指明入口函數(shù)
entry: {
app: './src/main.js'
},
// 輸出配置項
output: {
// 路徑,從config/index讀取的盖矫,值為:工程目錄下的dist目錄丽惭,需要的自定義的也可以去修改
path: config.build.assetsRoot,
// 發(fā)布路徑击奶,這里是的值為/,正式生產(chǎn)環(huán)境可能是服務(wù)器上的一個路徑,也可以自定義
publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,
filename: '[name].js'
},
// 配置模塊如何被解析责掏,就是import或者require的一些配置
resolve: {
// 當使用require或者import的時候正歼,自動補全下面的擴展名文件的擴展名,也就是說引入的時候不需要使用擴展名
extensions: ['', '.js', '.vue', '.json'],
// 當我們require的東西找不到的時候拷橘,可以去node_modules里面去找局义,
fallback: [path.join(__dirname, '../node_modules')],
// 別名,在我們require的時候,可以使用這些別名冗疮,來縮短我們需要的路徑的長度
alias: {
'vue$': 'vue/dist/vue.common.js',
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '../src/assets'),
'components': path.resolve(__dirname, '../src/components')
}
},
// 同上
resolveLoader: {
fallback: [path.join(__dirname, '../node_modules')]
},
// 對相應(yīng)文件的編譯使用什么工具的配置
module: {
// loader之前的配置萄唇,會對.vue,.js的文件用eslint進行編譯,include是包含的文件,exclude是排除的文件术幔,可以使用的正則
preLoaders: [
{
test: /\.vue$/,
loader: 'eslint',
include: [
path.join(projectRoot, 'src')
],
exclude: /node_modules/
},
{
test: /\.js$/,
loader: 'eslint',
include: [
path.join(projectRoot, 'src')
],
exclude: /node_modules/
}
],
// 這里也是相應(yīng)的配置另萤,test就是匹配文件,loader是加載器诅挑,
// query比較特殊四敞,當大小超過10kb的時候,會單獨生成一個文件拔妥,文件名的生成規(guī)則是utils提供的方法忿危,當小于10kb的時候,就會生成一個base64串放入js文件中
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
loader: 'babel',
include: [
path.join(projectRoot, 'src')
],
exclude: /node_modules/
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
// eslint的配置
eslint: {
formatter: require('eslint-friendly-formatter')
},
// vue-loader的配置
vue: {
loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),
postcss: [
require('autoprefixer')({
browsers: ['last 2 versions']
})
]
}
}
webpack.dev.conf.js
var config = require('../config')
var webpack = require('webpack')
// https://github.com/survivejs/webpack-merge 提供一個合并生成新對象函數(shù)
var merge = require('webpack-merge')
var utils = require('./utils')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var FriendlyErrors = require('friendly-errors-webpack-plugin')
// 在瀏覽器不刷新的情況下没龙,也可以看到改變的效果铺厨,如果刷新失敗了,他就會自動刷新頁面
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})
module.exports = merge(baseWebpackConfig, {
module: {
// 后面會有對utils的解釋,這里是對單獨的css文件硬纤,用相應(yīng)的css加載器來解析
loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
},
// 在開發(fā)模式下解滓,可以在webpack下面找到j(luò)s文件,在f12的時候筝家,
devtool: '#eval-source-map',
// 將webpack的插件放入
plugins: [
// 通過插件修改定義的變量
new webpack.DefinePlugin({
'process.env': config.dev.env
}),
// webpack優(yōu)化的這個一個模塊洼裤,https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.optimize.OccurrenceOrderPlugin(),
// 熱加載
new webpack.HotModuleReplacementPlugin(),
// 當編譯出現(xiàn)錯誤的時候,會跳過這部分代碼
new webpack.NoErrorsPlugin(),
// filename生成的文件名溪王,template是模版用的文件名,https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
// 讓打包生成的html文件中css和js就默認添加到html里面腮鞍,css就添加到head里面,js就添加到body里面
inject: true
}),
new FriendlyErrors()
]
})