目錄
1、Vue是什麼
vue是什麼,是一套構建用戶界面的漸進式框架。
vue兩大核心思想,組件化和數據驅動,組件化就是把一個整體拆分個一個一個的組件,組件可重複使用。數據驅動是前端未來的發展方向,釋放了對DOM的操作,讓DOM隨着數據的變化而自然的變化,不必過多的關注DOM,只需要將數組組織好即可。
2、node安裝
windows環境下的node安裝是很方便的,登錄官網http://nodejs.org/,找到對應的系統版本直接下載就行.
- 下載安裝包
LTS:追求穩定的開發用戶,可以下載這個版本,只需要每年十月一個版本的時候,進行升級。
Current:熱衷嘗試新特性,或者不在生產環境中的實現性項目可以下載這個版本。更新比較頻繁,切不保證兼容性。
- 安裝過程
安裝的時候直接next即可,window按照過程會提示添加path的系統變量,變量是你的安裝路徑,例如C:\Program Files\nodejs
- 測試
cmd輸入node -v 測試是否安裝成功,如果成功,會出現版本號
3、NPM
在用vue構建大型應用的時候,推薦使用npm安裝,npm能很好的喝webpack等打包工具進行配合。可以將npm鏡像設置爲淘寶npm鏡像,可以大幅度提升下載速度。詳情參考https://npm.taobao.org/。
- npm安裝
剛纔安裝了node,最新版本的node安裝包已經集成了npm,所以安裝node的同時也已經成功安裝了npm,測試npm是否安裝成功
- 安裝淘寶鏡像
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
- 安裝模塊
$ cnpm install [name]
- 同步模塊
$ cnpm sync connect
- 其他命令
$ cnpm info connect
4、cli安裝
Vue提供了的官方cli(命令行工具),爲單頁面應用(SPA)快速搭建繁雜的腳手架。可以幾分鐘之內快速構建一個項目運行起來
- 全局安裝cli
npm install --global vue-cli
5、快速構建項目
- 安裝node,npm,cli參考上文,同時在C:\Users\Andminster\AppData\Roaming\npm目錄下爲會生成幾個vue相關的文件
- 創建自己的項目,使用命令
在運行安裝命令以後,需要輸入一些命令,下面一個一個來解釋一下
- Project name 項目名稱,可以自己指定,也可以直接回車使用默認的名稱。注意這裏的名稱不能有大寫字母
- projuect description (A Vue.js project),項目描述,可以隨意寫,也可以不寫
- Author... 作者,隨意輸入吧
- 選擇題:
4.1、Runtime + Compiler: recommended for most users 運行加編譯,既然已經說了推薦,就選它了
4.2、Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specificHTML) are ONLY allowed in .vue files - render functions are required elsewhere 僅運行時,已經有推薦了就選擇第一個了 -
Install vue-router? (Y/n) 是否安裝vue-router 這是官方的路由,輸入y,使用官方路由
-
Use ESLint to lint your code? (Y/n) 是否使用ESLint管理代碼,是一個代碼風格管理工具,統一整體代碼風格,不會影響整體運行
-
Pick an ESLint preset (Use arrow keys) 選擇一個ESLint預設,編寫vue項目的代碼風格
-
選擇代碼標準
8.1、Standard (https://github.com/feross/standard) 標準,有些看不明白,什麼標準呢,去給提示的standardgithub地址 看一下, 原來時js的標準風格
8.2、AirBNB (https://github.com/airbnb/javascript) JavaScript最合理的方法,這個github地址說的是JavaScript最合理的 方法
8.3、none (configure it yourself) 這個不用說,自己定義風格
-
Setup unit tests with Karma + Mocha? (Y/n) 是否安裝單元測試,我選擇安裝
-
Setup e2e tests with Nightwatch(Y/n)? 是否安裝e2e測試 ,我選擇安裝
-
安裝成功
這幾個配置選擇yes 或者 no 對於我們項目最大的影響就是,如果選擇了yes 則生成的項目會自動有相關的配置,有一些loader我們就要配套下載。所以如果我們確定不用的話最好不要yes,要麼下一步要下很多沒有用的loader
6、vue-test目錄解析
新建項目目錄結構如圖所示:
- build 裏面是一些操作文件,使用npm run * 執行的都是這裏面的文件,主要是進行webpack的一些配置。對我們最有用並且可能會使用的就是webpack.base.config.js、webpack.dev.config.js、webpack.prod.config.js三個webpack的配置文件,分別是基本webpack配置、開發環境配置、生產環境配置。實際上這些文件裏面的內容,一些簡單的配置都已經有了,包括入口文件、插件、loader、熱更新等都已經配置好了。我們要做的只是根據自己的項目有什麼loader需要增加的,比如生成環境需要加上UglifyJsPlugin插件等可以自行配置,或者一些插件增加或者不需要的刪除,其實都是和業務相關了,其他的都可以不需要動
- config 配置文件,執行文件需要的配置信息,最主要的就是index.js 這個文件進行配置代理服務器,這個地方和我們息息相關,和後臺聯調就是在這裏設置一個地址就可以了。打開index.js 找到“proxyTable“這個屬性,然後在裏面加上對應的後臺地址即可
- node_modules,安裝的的模塊文件,npm install會把所有的模塊安裝下載,
- src資源文件,所有的組件和所用的圖片都是放在這裏,assets資源文件夾,放圖片之類的資源;components,組件文件夾,寫的所有的組件放在這個下面;router路由文件夾,這個也決定了頁面的跳轉規則;APP.vue應用組件,所有自己寫的組件,都是在這個裏面運行,vue文件入口界面;main.js,對應App.vue 創建vue實例,也是入口文件,對應webpack.base.config.js裏的入口配置,webpack四大特性entry入口、output輸出、loader加載器、plugins插件。
- static,存放的文件不會經過webpack處理,可以直接引用,
- test 單元測試和e2e測試的文件在此下面
- package.json, 這個文件很重要,有2部分很有用。script裏面設置命令,例如設置了dev用於調試,執行命令npm run dev,就是執行dev對應的命令,;設置了build,執行npm run build 用於打包;另外一部分,可以看到我們的依賴包,在dependencies和devDependencies中,分別對應全局下載和局部下載的依賴包
在其他博客看到更好更直觀更詳細的的目錄解析,記錄下來,加深記憶,方便查閱。
|-- build // 項目構建(webpack)相關代碼
| |-- build.js // 生產環境構建代碼
| |-- check-version.js // 檢查node、npm等版本
| |-- utils.js // 構建工具相關
| |-- vue-loader.conf.js // webpack loader配置
| |-- webpack.base.conf.js // webpack基礎配置
| |-- webpack.dev.conf.js // webpack開發環境配置,構建開發本地服務器
| |-- webpack.prod.conf.js // webpack生產環境配置
|-- config // 項目開發環境配置
| |-- dev.env.js // 開發環境變量
| |-- index.js // 項目一些配置變量
| |-- prod.env.js // 生產環境變量
|-- src // 源碼目錄
| |-- components // vue公共組件
| |-- router // vue的路由管理
| |-- App.vue // 頁面入口文件
| |-- main.js // 程序入口文件,加載各種公共組件
|-- static // 靜態文件,比如一些圖片,json數據等
|-- .babelrc // ES6語法編譯配置
|-- .editorconfig // 定義代碼格式
|-- .gitignore // git上傳需要忽略的文件格式
|-- .postcsssrc // postcss配置文件
|-- README.md // 項目說明
|-- index.html // 入口頁面
|-- package.json // 項目基本信息,包依賴信息等
---------------------
重點描述幾個重要文件
1、package.json文件
package.json文件是項目的配置文件,定義了項目的基本信息和相關依賴包,npm運行命令等
2. dependencies VS devDependencies
dependencies 是運行時依賴(生產環境) npm install --save **(package name)
devDependencies 是開發時的依賴(開發環境) npm install --save-dev **(package name)
dependencies是運行時候的依賴(生產環境),devDependencies是開發時候的依賴(開發環境),相應的npm install在安裝npm包的時候,有兩種命令參數可以把他們的信息寫入package.json文件,-save會把依賴包名添加到package.json文件dependencies 下面,–save-dev 則添加到 package.json 文件 devDependencies 鍵下。
舉個例子比如我們項目要引用jQuery,因爲jQuery部署到線上環境也要使用(生產環境),所以安裝jQuery的命令爲
npm install jQuery --save
這時候 dependencies 鍵下就會多了一個jQuery包。
3、基礎配置文件webpack.base.config.js
基礎的webpack配置文件主要根據模式定義了入口出口,以及處理vue.babel等模塊,是最爲基礎的部分,其他模式的配置文件以此爲基礎,通過webpck-merge合併。
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
// 獲取絕對路徑
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
// 定義一下代碼檢測的規則
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
})
module.exports = {
context: path.resolve(__dirname, '../'),//基礎目錄
entry: {
app: './src/main.js'//webpack入口文件
},
output: {
path: config.build.assetsRoot,//輸出目錄
filename: '[name].js',//輸出文件名稱
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath//生產模式
: config.dev.assetsPublicPath//開發模式
},
/**
*當webpack試圖去加載模塊的時候,他默認是查找.js結尾的文件的,
*並不知道.vue結尾的文件是什麼鬼玩意兒
*遇到.vue結尾的文件也要去加載
*進行如下配置
*/
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {//創建別名
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),// 如 '@/components/HelloWorld'
}
},
//模塊相應的配置,包括Loader,plugin等。不同模塊的處理規則,用不同的loader處理不同的文件
module: {
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,//vue要在babel之前,對所有的.vue文件使用vue-loader進行編譯,
loader: 'vue-loader',//vue轉普通的html
options: vueLoaderConfig//可選項:vue-loader選項配置
},
{
test: /\.js$/,//babel
loader: 'babel-loader',//es6 轉es5
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]// url-loader 文件大小低於指定的限制時,可返回 DataURL,即base64
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,//url-loader 圖片 對圖片資源使用url-loader
loader: 'url-loader',
options: {// 小於10K的圖片轉成base64編碼的dataURL字符串寫到代碼中
limit: 10000,// 默認無限制
name: utils.assetsPath('img/[name].[hash:7].[ext]') //其他的圖片轉移到靜態資源文件夾
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,// 對多媒體資源文件使用url-loader
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,//對字體資源文件使用url-loader
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {// 是否 polyfill 或 mock
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
4、開發環境配置文件,webpack.dev.config.js
啓動項目的時候就要用到這個文件,非常重要哦
// webpack開發環境配置
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')//基本配置的參數
const merge = require('webpack-merge')//webpack-merge是一個可以合併數組和對象的插件
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')//webpack基本配置文件,開發和運行時候公用
const CopyWebpackPlugin = require('copy-webpack-plugin')
/**
* HtmlWebpackPlugin description
* 這個插件的作用是依據一個簡單模板,幫你生成最終的html5文件
* 這個文件中自動引用了打包以後的js文件,每次編譯都在文件名中插入了一個不同的哈希值
* 即在index.html裏面加上<link>和<script>標籤引用webpack打包後的文件
*/
const HtmlWebpackPlugin = require('html-webpack-plugin')
//能夠更好的再終端看到webpack運行時候的錯誤和警告
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
//自動檢索下一個可用的端口
const portfinder = require('portfinder')
// 讀取系統環境變量的host
const HOST = process.env.HOST
// 讀取系統環境變量的port
const PORT = process.env.PORT && Number(process.env.PORT)
//合併baseWebpackConfig配置
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development 添加元信息(meta info)增強調試
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
///webpack-dev-server服務器配置
devServer: {
clientLogLevel: 'warning',//console控制檯顯示的消息,
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,//開啓熱加載
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,//開啓壓縮
host: HOST || config.dev.host,//HOST 優先
port: PORT || config.dev.port,//PORT 優先
open: config.dev.autoOpenBrowser,//自動打開瀏覽器,這裏是默認是false,所以不會自動打開
overlay: config.dev.errorOverlay// warning 和 error 都要顯示
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,//設置代理,用於前後端分離,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {//啓用watch模式,在初始構建之後,webpack將繼續監聽任何已解析的文件的更改
poll: config.dev.poll,//通過傳遞true,開啓polling.或者指定毫秒爲單位進行輪詢
}
},
plugins: [//webpack一些構建用到的插件
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
//模塊熱替換,運行再運行的時候更新模塊,無需進行全部刷新
new webpack.HotModuleReplacementPlugin(),
// 熱加載時,直接返回更新的文件名,而不是id
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
// 跳過編譯時出錯的代碼並記錄下來,主要作用是使編譯後運行時的包不出錯
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
// 指定編譯後生成的html文件
filename: 'index.html',
// 需要處理的模板
template: 'index.html',
// 打包過程中輸出的js、css的路徑添加到html文件中
// css文件插入到head中
// js文件插入到body中,可能的選項有 true, 'head', 'body', false
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port //獲取當前設定的端口
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests 發佈新的端口,對於e2e進行測試
process.env.PORT = port
// add port to devServer config 設置devServer端口
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
5、生產模式配置文件webpack.prod.conf.js
// webpack生產環境配置
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
// copy-webpack-plugin ,用於static的靜態資源文件夾複製到產品文件夾dist.
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
// optimize-css-assets-webpack-plugin 優化和最小化css文件
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
// uglifyJs 混淆js插件
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: require('../config/prod.env')
const webpackConfig = merge(baseWebpackConfig, {
module: {
/**
*樣式文件的處理規則,對css sass scss等不同內容使用相應的styleloaders
*utile配置出各種預處理語言使用的loader
*/
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,//production 下生成 sourceMap
extract: true,//util 中 styleLoaders 方法內的 generateLoaders 函數
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
// webpack輸出路徑和命名規則
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new UglifyJsPlugin({//js 代碼壓縮還可配置 include, cache 等,也可用 babel-minify 醜化壓縮JS代碼
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config.build.productionSourceMap,
parallel: true// 充分利用多核cpu
}),
// extract css into its own file 提取文件中的css 將css提取到單獨的文件
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
// 優化、最小化css代碼,如果只簡單使用extract-text-plugin可能會造成css重複
// 具體原因可以看npm上面optimize-css-assets-webpack-plugin的介紹
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
// 將產品文件的引用注入到index.html
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
template: 'index.html',
inject: true,
minify: {
// 刪除inde.html文件中的註釋
removeComments: true,
//刪除index.html裏面 空格
collapseWhitespace: true,
// 刪除各種html標籤屬性值的雙引號
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
// 注入依賴的時候按照依賴先後順序進行注入,比如,需要先注入vendor.js,再注入app.js
chunksSortMode: 'dependency'
}),
// keep module.id stable when vendor modules does not change 按 dependency 的順序引入
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
// 從vendor中提取出manifest,原因如上
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// copy custom static assets
// 將static文件夾裏面的靜態資源複製到dist/static
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
// 如果開啓了產品gzip壓縮,則利用插件將構建後的產品文件進行壓縮
if (config.build.productionGzip) {
// 一個用於壓縮的webpack插件
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip', // 壓縮算法
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
// 如果啓動了report,則通過插件給出webpack構建打包後的產品文件分析報告
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
6、build.js編譯入口
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'//設置當前環境爲生產環境
const ora = require('ora')//loading.. 進度條
const rm = require('rimraf')//刪除文件
const path = require('path')
const chalk = require('chalk')//顏色設置
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
// 清空文件夾
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
// 刪除完成回調函數內,執行編譯
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
// 編譯完成,輸出文件
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
//失敗
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
// 成功
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
7. 實用代碼段 utils.js
'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const packageConfig = require('../package.json')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)//posix方法修正路徑
}
/**
* options
* 示例: ({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
*/
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified 生產模式中提取css
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
// 返回各種 loaders 對象
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
// 配合 friendly-errors-webpack-plugin
exports.createNotifierCallback = () => {
// 基本用法:notifier.notify('message');
const notifier = require('node-notifier')
// 當前設定是隻有出現 error 錯誤時觸發 notifier 發送通知
return (severity, errors) => {
if (severity !== 'error') return //嚴重程度可以是 'error' 或 'warning'
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}
8、babel配置文件.babelrc
{//設定轉碼規則
"presets": [
["env", {
"modules": false,
//對BABEL_ENV或者NODE_ENV指定的不同的環境變量,進行不同的編譯操作
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
//轉碼用的插件
"plugins": ["transform-vue-jsx", "transform-runtime"],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]
}
}
}
9、編碼規範.editorconfig
root = true
[*] // 對所有文件應用下面的規則
charset = utf-8 // 編碼規則用utf-8
indent_style = space // 縮進用空格
indent_size = 2 // 縮進數量爲2個空格
end_of_line = lf // 換行符格式
insert_final_newline = true // 是否在文件的最後插入一個空行
trim_trailing_whitespace = true // 是否刪除行尾的空格
10、 .src/main.js文件解讀
main.js是整個項目的入口文件
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
//生產環境提示,這裏設置成了false
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>' ///引入App組件
})
11、.src/app.vue文件解讀
<template>
<div id="app">
<img src="./assets/logo.png">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
template標籤包裹的內容:模板htmldom的結構
script標籤包含的js內容,可以在這裏寫一些頁面的js邏輯代碼
style樣式文件
12、 src/router/index.js 路由文件
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)
export default new Router({
routes: [//配置路由
{
path: '/',//訪問路徑
name: 'HelloWorld',//訪問名稱
component: HelloWorld//路由需要的組件
}
]
})
7 、項目運行詳解
創建好項目以後,進入到vue-test目錄,運行如下命令,啓動項目。
cd vue-test
npm run dev
瀏覽器輸入地址:localhost:8081 打開頁面(默認端口:8080)
啓動成功以後沒有默認打開瀏覽器,木關係,修改一下配置文件。找到根目錄文件package.json-->script-->dev,在命令行中增加open命令,默認啓動的時候打開瀏覽器
8、總結
構建項目總結起來一共只有四步
- 安裝node、npm
- npm install --global vue-cli 下載vue-cil腳手架
- vue init webpack vue-test 生成項目,形成基本結構
- npm run dev 運行