一步一步創(chuàng)建vue2.0項(xiàng)目
vue2.0已經(jīng)發(fā)正式版本了勇垛,來研究一下吧
新建一個文件夾 vue2.0-learn 胡陪。前提是默認(rèn)已經(jīng)安裝了nodejs和npm
npm init
按照步驟初始化package.json伸刃,這個文件提供了這個項(xiàng)目需要的全部信息拴驮,包括name庸汗,version,依賴包等等其他的信息山上。文件內(nèi)容本身是一個JSON字符串眼耀,不僅僅是一個javascript對象。
然后我們得到了一個package.json文件
npm install vue --save
由于vue的默認(rèn)版本已經(jīng)是2.0+了佩憾,所以直接不加版本號安裝哮伟,就已經(jīng)是2.0+了,如果需要安裝其他版本號妄帘,可以加版本好安裝楞黄,例如npm install veu@1.0.0--save,--save的作用是安裝之后自動加入到package.json的dependencies依賴列表里面
復(fù)雜頁面必然要模塊化抡驼、組件話」砝現(xiàn)在最流行的模塊打包工具莫過于webpack,用過vue1.0和react之類的框架就很熟悉了
npm install webpack --save-dev
這里為什么是--save-dev是因?yàn)檫@種腳手架類的安裝包致盟,不需要打包到框架中去碎税,只有開發(fā)者才會使用到。就不需要放到dependencies勾邦,而是放到devDependencies里面去
web開發(fā)自然是需要一個web服務(wù)器容器的蚣录,我們可以使用各種服務(wù)器,這里我們使用webpack-dev-server眷篇,webpack自帶的server萎河,因?yàn)楹蛍ebpack結(jié)合的更緊密,也有很多更好用的功能
npm install webpack-dev-server --save-dev
es6語法已經(jīng)很流行了蕉饼,使用es6語法虐杯,帶來很多更好的開發(fā)體驗(yàn)。webpack自帶loader解析器昧港,可以根據(jù)需要配置loader插件擎椰,解析es6語法,我們使用babel
npm install babel-core babel-loader babel-plugin-transform-runtime babel-preset-es2015 babel-preset-stage-2 --save-dev
安裝完之后创肥,在項(xiàng)目根目錄下面新建一個.babelrc文件达舒,這是babel的配置文件
{
"presets": ["es2015", "stage-2"],
"plugins": ["transform-runtime"],
"comments": false
}
下面開始業(yè)務(wù)代碼的編寫,新建一個index.html文件
新建一個src文件夾叹侄,這里面放置的是源代碼
新建一個App.vue文件巩搏,這個是項(xiàng)目根組件,使用的是vue單文件的組織方式趾代,代碼如下:
export default {
? name: 'app',
? data() {
? return {
? ? msg: '我是誰贯底!'
? }
? },
? mounted() {
? },
? methods: {
? },
? components: {
? }
}
創(chuàng)建main.js,這個文件是項(xiàng)目初始化文件撒强。代碼如下:
import Vue from 'vue'
import App from './App'
new Vue({
el: '#app',
template: '',
components: { App }
})
下一步開始創(chuàng)建webpack文件禽捆。
一般我們的代碼會區(qū)分開發(fā)環(huán)境和生產(chǎn)環(huán)境笙什,開發(fā)環(huán)境不需要壓縮代碼,需要可以調(diào)試胚想。
而生產(chǎn)環(huán)境則需要壓縮琐凭,去除調(diào)試代碼等等其他一系列區(qū)別的事情。
所以我們先新建兩個文件:dev.js和prod.js顿仇,先創(chuàng)建dev.js淘正,這是開發(fā)環(huán)境webpack配置
var path = require('path')
module.exports = {
// 項(xiàng)目根目錄
context: path.join(__dirname, '../'),
// 項(xiàng)目入口
entry: [
? './src/main.js'
],
// 打包編譯生成文件配置
output: {
? path: path.join(__dirname, '../build'), // 編譯文件存儲目錄
? filename: 'index.js',? // 編譯后的入口文件
? publicPath: '/build/',? // devServer訪問的路徑前綴
? chunkFilename: '[name]-[chunkhash:8].js' // 編譯的分塊代碼可以使用文件hash作為文件名,按需加載的時(shí)候會產(chǎn)生
},
resolve: {
? extensions: ['', '.js', '.vue'],? // 引入文件的默認(rèn)擴(kuò)展名
? alias: {
? vue: 'vue/dist/vue.js'? //別名配置 解決vue template 警告bug
? }
},
module: {
? loaders: [
? {
? ? test: /\.vue$/,
? ? loader: 'vue'
? },
? {
? ? test: /\.js$/,
? ? loader: 'babel',
? ? exclude: /node_modules/
? },
? {
? ? test: /\.css$/,
? ? loader: "style!css",
? ? include: __dirname
? },
? {
? ? test: /\.less$/,
? ? loader: "style!css!less",
? ? include: __dirname
? }
? ]
}
}
好了,一個簡單的webpack config文件就創(chuàng)建好了臼闻,切換到項(xiàng)目根目錄,運(yùn)行webpack--config./webpack/dev.js囤采,可以看到在根目錄下面生成一個build文件夾述呐,下面有個index.js文件,這個就是生成的可以瀏覽器運(yùn)行的文件
直接修改index.html文件蕉毯,添加一行
?
?
在瀏覽器里面打開這個頁面乓搬,OK,不出意外的是可以運(yùn)行的代虾。
然而web開發(fā)我們并沒有使用服務(wù)器进肯,這會有很多限制,比如加載文件棉磨,ajax請求等等江掩,所以我們使用了上文提到的webpack-dev-server。使用這個可以快速啟動一個本地server乘瓤,和webpack配合起來還有很多其他功能环形,比如http代理,history api等功能
var webpackDevServer = require('webpack-dev-server');
var webpack = require("webpack");
var webpackConfig = require('../webpack/dev');
var config = require('../config')
var compiler = webpack(webpackConfig);
var server = new webpackDevServer(compiler, {
stats: {
? colors: true // 控制臺輸出帶顏色
},
historyApiFallback: {
? index: '/index.html' // history api 會定位到的頁面
},
publicPath: webpackConfig.output.publicPath, // 編譯文件的前綴
proxy: {? // http代理
}
});
server.listen(config.port, err => {
if (err) {
? console.log(err)
? return
}
console.log(`Listening at http://${config.address}:${config.port}\n`)
});
module.exports = server
這時(shí)候直接瀏覽器訪問http://localhost:9999衙傀,直接可以訪問到我們剛剛看到的相同的頁面抬吟,而且默認(rèn)開始了watch功能,修改之后直接編譯了统抬,不需要在重新運(yùn)行webpack了
這時(shí)候我們回過頭去看webpack的dev配置火本,好像太過于簡陋了
因?yàn)闉g覽器里面加載到的是編譯之后的代碼,所以這非常不利于我們打斷點(diǎn)聪建,不過幸好钙畔,現(xiàn)代瀏覽器都支持sourceMap功能,webpack配置起來也很簡單
context: path.join(__dirname, '../'),
devtool: 'source-map',
加上這一句話妆偏,再重新運(yùn)行一下程序我們就看到除了生成index.js文件之外刃鳄,還生成了index.js.map文件,這里面就是源文件钱骂,我們可以在chrome的source下面的webpack文件夾下面看到對應(yīng)我們書寫的源文件了叔锐,我們在這邊打斷點(diǎn)調(diào)試了
如果有瀏覽器自動刷新就更好了挪鹏,更新如下
var path = require('path')
var config = require('../config')
var webpack = require('webpack')
entry: [
? './src/main.js',
? `webpack-dev-server/client?http://${config.address}:${config.port}`,
? 'webpack/hot/only-dev-server',
],
plugins: [
? new webpack.HotModuleReplacementPlugin()
]
沒有代碼檢查,怎么做團(tuán)隊(duì)協(xié)作啊愉烙,我們使用比較火的eslint
新建一個文件.eslintrc
{
"root": true,
"parser": "babel-eslint",
"env": {
? "browser": true
},
"parserOptions": {
? "sourceType": "module"
},
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
"extends": "standard",
// required to lint *.vue files
"plugins": [
? "html"
],
// add your custom rules here
"rules": {
? // allow paren-less arrow functions
? "arrow-parens": 0,
? // allow async-await
? "generator-star-spacing": 0,
? //
? "space-before-function-paren": ["error", { "anonymous": "always", "named": "never" }]
}
}
修改webpack文件
? preLoaders: [
? {
? ? test: /\.vue$/,
? ? loader: 'eslint',
? ? exclude: /node_modules|assets/
? },
? {
? ? test: /\.js$/,
? ? loader: 'eslint',
? ? exclude: /node_modules|assets/
? }
? ]
下面就要安裝我們需要的依賴包了
npm install babel-eslint eslint-plugin-html eslint eslint-config-standard eslint-plugin-standard eslint-plugin-promise eslint-friendly-formatter eslint-loader --save-dev
安裝完成讨盒,測試可以了,已經(jīng)開始檢測代碼了步责,看起來舒服多了返顺,順便把代碼格式化一下吧。
還記得我們在之前的index.html里面手動插入了一行script引入了代碼蔓肯,這個腳本是我們通過webpack生成的遂鹊,我們在webpack里面指定了名稱,我們需要在html里面需要寫一個一模一樣的名稱蔗包,同樣的代碼我們維護(hù)了兩遍秉扑,這是不能忍的
這里我們使用到一個插件HtmlWebpackPlugin,可以自動在script標(biāo)簽中插入script
npm install html-webpack-plugin --save-dev
事實(shí)勝于雄辯调限,以上的解決方案并不適合舟陆。因?yàn)閣ebpackDevSever生成的文件是存儲在內(nèi)存里面的,使用historyApiFallback定位不到耻矮,所以還是在index.html里面維護(hù)這個script的引用吧
上文提到我們需要本地開發(fā)和發(fā)布到線上去秦躯,線上服務(wù)器環(huán)境肯定是不能使用webpack-dev-server的,我們是需要生成真實(shí)的文件存儲到磁盤上裆装,發(fā)布到服務(wù)器環(huán)境上去踱承,所以我們需要一份prod的webpack配置文件。
npm install webpack-merge --save-dev
調(diào)整之后的webpackBase.js文件如下
var path = require('path')
var webpack = require('webpack')
module.exports = {
// 項(xiàng)目根目錄
context: path.join(__dirname, '../'),
// 項(xiàng)目入口
entry: [
? './src/main.js'
],
// 打包編譯生成文件配置
output: {
? path: path.join(__dirname, '../build'), // 編譯文件存儲目錄
? filename: 'index.js',? // 編譯后的入口文件
? publicPath: '/build/',? // devServer訪問的路徑前綴
? chunkFilename: '[name]-[chunkhash:8].js' // 編譯的分塊代碼可以使用文件hash作為文件名,按需加載的時(shí)候會產(chǎn)生
},
resolve: {
? extensions: ['', '.js', '.vue'],? // 引入文件的默認(rèn)擴(kuò)展名
? alias: {
? vue: 'vue/dist/vue.js'? // 解決vue template 警告bug
? }
},
module: {
? preLoaders: [
? {
? ? test: /\.vue$/,
? ? loader: 'eslint',
? ? exclude: /node_modules|assets/
? },
? {
? ? test: /\.js$/,
? ? loader: 'eslint',
? ? exclude: /node_modules|assets/
? }
? ],
? loaders: [
? {
? ? test: /\.vue$/,
? ? loader: 'vue'
? },
? {
? ? test: /\.js$/,
? ? loader: 'babel',
? ? exclude: /node_modules/
? },
? {
? ? test: /\.css$/,
? ? loader: "style!css",
? ? include: __dirname
? },
? {
? ? test: /\.less$/,
? ? loader: "style!css!less",
? ? include: __dirname
? }
? ]
},
plugins: []
}
dev文件如下:
var config = require('../config')
var webpack = require('webpack')
var merge = require('webpack-merge')
var baseConfig = require('./base')
module.exports = merge(baseConfig, {
devtool: 'source-map',
entry: [
? ...baseConfig.entry,
? `webpack-dev-server/client?http://${config.address}:${config.port}`,
? 'webpack/hot/only-dev-server',
],
plugins: [
? ...baseConfig.plugins
]
})
prod.js如下
var merge = require('webpack-merge')
var baseConfig = require('./base')
var fs = require('fs')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var scriptReg = /.*<\/script>/mgi
var template = fs.readFileSync('./index.dev.html', 'utf8')
if(!template){
throw '獲取模版失敗'
}
var templateContent = template.replace(scriptReg, '')
module.exports = merge(baseConfig, {
plugins: [
? ...baseConfig.plugins,
? new HtmlWebpackPlugin({
? filename: '../../index.html',
? hash: true,
? templateContent: templateContent,
? minify: false,
? inject: true
? })
]
})
運(yùn)行webpack--config./webpack/prod.js會看到生成的文件米母,到時(shí)候我們只需要把這些文件上傳到服務(wù)器就OK了
添加npm script的勾扭,快速運(yùn)行
"scripts": {
? "dev": "node ./server/index.js",
? "prod": "webpack --config ./webpack/prod.js",
? "test": "echo \"Error: no test specified\" && exit 1"
}
至此,環(huán)境配置結(jié)束