vue-cli2 和vue-cli3的對比

分享一篇不錯的文章,摘自:www.360doc.com/content/18/…css


www.360doc.com/content/18/…
html

Vue CLI 產生的背景

在Vue CLI出現以前,你可能要花費好幾天的時間搭建項目的開發環境,若是你事先不瞭解webpack,你可能會又花費大把的時間熟悉webpack。就這樣,一週過去了,你的項目尚未真正啓動起來。 爲了讓開發者從糾結配置中解放出來,專一於撰寫應用程序。Vue CLI也就所以而產生。它不只確保了各類構建工具可以基於智能的默認配置便可平穩銜接,還提供了配置調整的靈活性。前端

Vue CLI歷史

Vue CLI到目前爲止經歷了兩個大版本,CLI 2 和 CLI 3。不少人可能會好奇從 CLI 2升級到CLI 3會有哪些新的改變,接下來就一邊回顧CLI 2,一邊爲你們解讀CLI 3的新特性。vue

建立一個項目

CLI 2和CLI 3第一個區別是npm包的包名,CLI 3並無沿用CLI 2的vue-cli,而是另起爲@vue/cli。建立項目方面也發生了變化,CLI 2 能夠選擇根據模板初始化項目,而CLI 3並未從新開發模板,若是開發者想要像CLI 2同樣使用模板初始化項目,可全局安裝一個橋接工具@vue/cli-init。node

一、CLI 2 全局安裝並建立項目react

npm install -g vue-cliwebpack

# 或者git

npm install -g vue-cli@x.x.x // 指定安裝某一版本github


vue init <template-name> <project-name>web

# 例如:vue init webpack vue-test

注意:這裏的CLI 2是2.9.6。

<template-name>:表示模板名稱,能夠經過vue list查看可用的模板,在這裏官方提供了6種模板,分別爲:

  • browserify——一個全面的Browserify vueify 的模板,運行起來帶有熱重載,保存時 lint 校驗,單元測試。

  • browserify-simple——一個簡單Browserify vueify的模板,不包含其餘功能,讓你快速的搭建vue的開發環境。

  • pwa——一個基於webpack模板的漸進式的網頁應用程序模板。

  • simple——一個最簡單的單頁應用模板。

  • webpack——一個全面的webpack vue-loader的模板,運行起來帶有熱重載,保存時 lint 校驗和CSS擴展。

  • webpack-simple——一個簡單webpack vue-loader的模板,能讓你快速搭建一個vue的開發環境。

圖1 官方提供的6種模板

初始化過程當中會確認項目的項目名、做者等信息,你們可根據需求自行修改。

二、CLI 3全局安裝並建立一個項目

npm install -g @vue/cli# 或者yarn global add @vue/cli# 建立項目vue create <project-name># 例如:vue create vue-3.0-demo# 或# 使用init 初始化項目npm install -g @vue/cli-init# `vue init` 的運行效果將會跟 `vue-cli@2.x` 相同vue init webpack vue-3.0-demo複製代碼

當咱們用CLI 3的方式建立項目,輸入vue create vue-3.0-demo命令後,你會發如今建立項目的路上老是有位「記者大哥」橫路攔截,問你這問你那,你還必須作出選擇。

故事就從你輸入vue create vue-3.0-demo後悄悄開始了...

記者大哥:「歡迎進入CLI 3的世界,首先你得選取一個 preset。選擇默認的設置能夠快速建立一個新項目的原型,而手動設置則提供了更多的選擇。你是選擇默認配置,仍是手動選擇特性呢?」

你:(內心活動:「來都來了,爲什麼不看看記者大哥到底搞什麼鬼」)「我選擇了手動選擇屬性」

圖2 手動選取特性

你:什麼鬼?還給我來個多選題!首先Babel是必要的,否則拿什麼來轉換ES6語法,TypeScript?不會,略過。漸進式的程序應用,暫時也不涉及這個。Router勾上,做爲一個移動M站,得有人來管理路由呀。Vuex一個狀態管理器,後期要用再加上吧,反正也跑不了。css 預處理器,習慣使用Less,也加一。Linter / Formatter也加一,做爲一個團隊,沒有人統一代碼風格可不行。最後兩個分別是單元測試和端對端測試,這裏我就不加上了,沒用過,期待從此有大神分享。

選擇完特性後,你覺得就結束了,沒想到,一步選錯步步要你選。

對於css預處理器方面,你毅然決然選擇了Less; 但linter / formatter 配置,你懵逼了。這都是什麼??記者大哥介紹了一下:

ESLint 是一個語法規則和代碼風格的檢查工具,能夠檢測出你代碼中潛在的問題,能夠保證寫出語法正確和風格統一的代碼。

圖3 選擇linter配置

  • ESLint with error prevention only——只檢測錯誤。

  • ESLint Airbnb config——獨角獸公司的Airbnb,有人評價說「這是一份最合理的JavaScript編碼規範」,它幾乎涵蓋了JavaScript的各個方面。

  • ESLint Standard config——standardJs一份強大的JavaScript編碼規範,自帶linter和自動代碼糾正。沒有配置。自動格式化代碼。能夠在編碼早期發現規範問題和低級錯誤。

  • ESLint Prettier—— Prettier 做爲代碼格式化工具,可以統一整個團隊的代碼風格。

等他介紹完,你內心大概有點譜了,這裏你選擇了 ESLint Standard config。

lint有兩種檢查時機,一是用戶保存文件的時候,二是用戶提交文件到git的時候。你就選了Lint on save,有錯及時解決嘛。

終於「記者大哥」告訴你接下來這個問題是最後一個問題咯。

記者大哥:你是喜歡把Babel、ESLint等配置信息全放在package.json文件裏呢,仍是單獨文件管理?

你:一個一個文件比較好,根據文件名就知道這是誰的配置,方便維護。

記者大哥:那你是否想把今天你手動選擇的preset保存爲將來項目的preset呢?

你:

說好的最後一個呢!!

......保存!

happy end~~

舒適提示

若是你是用window,在進行建立項目的時候,最好使用cmd,在cmd裏你能夠經過箭頭上下選擇和空格選中。若是你用git bash 可能會出現箭頭和空格都沒有請選擇和選中做用。

這裏經過一個漫長的對話咱們自定義的一個preset,此時若是你須要建立新工程,這時候你就會發現多了一個preset,就是最初你本身設置的。你能夠選擇本身以前保存preset的,也能夠再次開啓「採訪模式」。

圖4 新添的preset

CLI 2 的項目結構

圖5 vue cli 2.9.6項目結構

對於CLI 2這個項目結構,主要的也是最重要的在於bulid和config者兩個目錄。bulid是項目構建的相關代碼,config是項目開發環境配置。

接下來就先從webpack.base.conf.js開始依次介紹build和config兩個目錄下的相關功能。

webpack.base.conf.js

webpack.base.conf.js是webpack的基礎配置,是dev和prod的公共配置文件。

const path = require('path')

const utils = require('./utils')

const config = require('../config')

const vueLoaderConfig = require('./vue-loader.conf')

  • path——該模塊提供了一些用於處理文件路徑的小工具

  • utils——給整個CLI提供方法

  • config——開發環境的配置

  • vueLoaderConfig——分析是不是生產環境,而後將根據不一樣的環境來加載配置功能

在這個文件裏一共實現了兩個方法。一是合併path路徑的,另外一個是建立Eslint的Rules。而剩餘部分就是webpack的基礎配置,這裏簡化了webpack結構,簡化的結果其實就是webpack的一個骨架,若是在配置上遇到問題,可去webpack查證。

...module.exports = {  entry: {}, // 編譯入口文件  output: {}, // 編譯輸出路徑  resolve: {}, // 一些解決方案配置  module: {    // 不一樣類型文件加載器配置    rules: []  },  ...  // 這些選項用於配置polyfill或mock某些node.js全局變量和模塊。  // 這可使最初爲nodejs編寫的代碼能夠在瀏覽器端運行  node: {...}}複製代碼

關於path有興趣的可前往node學習,接下來重點介紹下utils.js,config和vue-loader.conf。

utils.js

utils.js文件中總共實現了4個方法:assetsPath、cssLoaders、styleLoaders、createNotifierCallback。

  • assetsPath——返回不一樣環境下的static目錄位置

  • cssLoaders——爲不一樣的css預處理器提供一個統一的生成方式

  • styleLoaders——爲那些獨立的style文件建立加載器配置

  • createNotifierCallback——以相似瀏覽器的通知的形式展現信息

config

config關鍵文件是index.js。這個文件是開發環境和生產環境的基本配置。在這個文件裏開發者可在dev設置開發環境的靜態路徑、本地服務器配置項、Eslint、SourceMaps和代理,也可在build設置生產環境是否開啓gzip壓縮,以及壓縮後綴名的設置等。

...

module.exports = {

dev: {...},

build: {...}

}

vue-loader.conf

這個文件的內容相對比較少。首先,vue文件中的css loader將在生產環境下把css文件抽取到一個獨立的文件中;其次是根據不一樣的環境,引入不一樣的source map配置文件;最後設置是否開啓緩存破壞。

'use strict'const utils = require('./utils')const config = require('../config')const isProduction = process.env.NODE_ENV === 'production'const sourceMapEnabled = isProduction  ? config.build.productionSourceMap  : config.dev.cssSourceMapmodule.exports = {  loaders: utils.cssLoaders({    sourceMap: sourceMapEnabled,    extract: isProduction  }),  cssSourceMap: sourceMapEnabled,  cacheBusting: config.dev.cacheBusting,  transformToRequire: {    video: ['src', 'poster'],    source: 'src',    img: 'src',    image: 'xlink:href'  }}複製代碼

關於webpack公共配置講完了,接下來咱們就一塊兒學習下在dev和prod環境各自的配置吧。

webpack.dev.conf.js

這個文件引入了webpack-merge,意在將公共配置文件和dev配置合併。從代碼裏咱們能夠發現,dev環境又新增了一些配置項。

  • 給獨立的style文件添加了sourceMap功能,有了它,出錯的時候,除錯工具將直接顯示原始代碼,而不是轉換後的代碼。

  • 引入devtool。

  • 配置devServer,包括熱部署、代理、啓動程序的時候自動在瀏覽器打開主頁面等。

  • 新增一些插件,包括熱替換、webpack.NamedModulesPlugin在熱加載時直接返回更新文件名、html-webpack-plugin生成html文件等。

最後一個函數是爲了確保啓動程序時,若是端口被佔用時,會經過portfinder來發布新的端口。

...

const devWebpackConfig = merge(baseWebpackConfig, {

module: { ... },

devtool: config.dev.devtool,

devServer: { ... },

plugins: [ ... ]

})


module.exports = new Promise((resolve, reject) => { ... })

webpack.prod.conf.js

相比 webpack.dev.conf.js,這個文件多引入了幾個依賴,主要是爲了壓縮CSS和JS。在文件配置上多了一個output,將js文件打包成多個chuck,用hash值命名,來解決緩存策略。

到這裏CLI 2的整個配置也就接近尾聲了。剩下的還有check-version.js和bulid.js兩個文件。

check-version.js

這個文件主要是用來檢測當前環境中的node和npm版本和咱們須要的是否一致的。

bulid.js

這個文件剛開始經過check-versions判斷當前的node和npm版本號,若是現有的npm或者node的版本比定義的版本低,則生成一段警告。接下來,先刪除打包目標目錄下的文件,再進行打包,直至打包完成。

咱們蜻蜓點水的學習了CLI 2的配置,估計你們也都累了。那接下來就來一段採訪吧~~期待不,哈哈。

CLI 3的項目結構

圖6 CLI 3項目結構

從CLI 3的整個項目結構咱們能夠發現,這個結構很簡單,沒有相關的配置文件或複雜的目錄結構。CLI 3僅生成構建應用程序所需的文件,讓使用者不用關心這些工具的具體配置,從而下降了工具的使用難度。

其實經過閱讀CLI 3的官方文檔,你可能已經知道,官方內置了一個CLI服務(@vue/cli-service),做爲一個開發環境的依賴,局部安裝在@vue/cli建立的項目中。若是你真想修改webpack的相關配置,可在項目的根目錄下(和package.json同級)建立一個vue.config.js配置文件,這個文件一旦存在就會被@vue/cli-service自動加載。也可直接使用package.json中的vue字段。

一個沒有好奇心的程序猿,不是一個更好的程序猿。

若是你已經知足於官方的介紹,那也就到此結束漫長的閱讀之旅啦(偷偷告訴你後面還有新特性的精彩內容)。若是你也像我同樣,充滿了好奇心,就跟我再去探索一番。

從CLI 2到CLI 3,初期可能沒有官方文檔。若是你真想探個究竟,能夠從啓動項目入手。

CLI 2啓動方式是webpack-dev-server --inline --progress --config build/webpack.dev.conf.js這裏用webpack-dev-server搭一個服務。

  • --inline:啓動inline模式來自動刷新頁面

  • --progress:顯示打包的進度

  • --config build/webpack.dev.conf.js:指定要用的是哪一個配置文件

CLI 3啓動方式是vue-cli-service serve

vue-cli-service就是CLI服務,你可全局搜索一下,位於node_modules\@vue\cli-service\bin

vue-cli-service.js

#!/usr/bin/env nodeconst semver = require('semver')const { error } = require('@vue/cli-shared-utils')const requiredVersion = require('../package.json').engines.node...const Service = require('../lib/Service')const service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())const rawArgv = process.argv.slice(2)const args = require('minimist')(rawArgv)const command = args._[0]service.run(command, args, rawArgv).catch(err => { error(err) process.exit(1)})複製代碼

這個文件首先是判斷了當前node的版本和vue-cli-service要求的版本是否一致,若是版本過低就得升級node版本。

緊接着就起了個服務,這個服務是位於lib/Service。

Service.js

...

loadUserOptions () {

// vue.config.js

let fileConfig, pkgConfig, resolved, resovledFrom

const configPath = (

process.env.VUE_CLI_SERVICE_CONFIG_PATH ||

path.resolve(this.context, 'vue.config.js')

)

...


// package.vue

pkgConfig = this.pkg.vue

...


if (fileConfig) {

if (pkgConfig) {

...

}

resolved = fileConfig

resovledFrom = 'vue.config.js'

} else if (pkgConfig) {

resolved = pkgConfig

resovledFrom = ''vue' field in package.json'

} else {

resolved = this.inlineOptions || {}

resovledFrom = 'inline options'

}

...

return resolved

}

}

...

在loadUserOptions這個函數中,你能夠看到官方提到的vue.config.js。 這個函數主要是加載用戶的配置。若是vue.config.js和package.json的vue字段同時存在,會忽略package.json的vue字段配置,而選取vue.config.js的配置。

這裏粗略介紹了何處加載了 vue.confg.js 文件,有興趣能夠繼續深究。通過安裝CLI、建立項目到整個項目結構介紹,咱們能夠大體瞭解了二者的區別。接下來你們一塊兒圍觀一下CLI 3給咱們帶來的哪些新特性吧~~~

新特新

CLI插件的出現

據我所知,在CLI 3以前是沒有CLI插件這個概念的,人們在開發Vue項目時,如果須要實現功能都是引用npm的相關包。CLI 3的出現,帶來了CLI插件這個概念,也帶來了統一的命名方式:@vue/cli-plugin-(內建插件)/ vue-cli-plugin-(社區插件)開頭。

圖7 CLI 3出現前包名

圖8 CLI插件

即刻建立原型

有時候你想快速建立一個原型,不須要添加一大堆樣板。Vue CLI就提供了一個運行原型的開發服務器。

要想使用這個開發服務器,前提是安裝@vue/cli-service-global

npm install -g @vue/cli-service-global複製代碼

你能夠用IDE建立.vue文件,並添加vue代碼。若是你對命令行掌握良好,也能輕鬆建立。

echo 'hello world' > src/views/HelloWorld.vue

而後將HelloWorld.vue 修改成標準的vue文件結構就行。

<template>  <div>hello world!</div></template>複製代碼

緊接着你就能夠運行vue serve src/views/HelloWorld.vue 就能看效果啦~

圖9 快速原型開發

配置時無需Eject

若是你曾經是一位React的忠實用戶,或許使用過create-react-app(react的腳手架),那你對eject的理解可能就很深入了。惋惜小女不才,早期與React只有一面之緣,也就沒此機會接觸create-react-app。爲了理解eject究竟是何物,我查看了react的相關文檔,終於明白了。 在react中,使用CRA( create-react-app簡稱)建立完項目,咱們能夠在package.json看到這裏一個script命令。

'scripts': {

'eject': 'react-scripts eject'

}

執行完npm run eject會將封裝在CRA裏的配置所有

反編譯
到當前項目,換句話就是把以前好不容易藏好了config文件暴露出來了,用戶也就獲取到了控制權,想怎麼改隨你。這樣react-scripts就以文件的形式存在於項目中,就沒法升級啦。

# eject 後項目根目錄下會出現 config 文件夾,裏面就包含了 webpack 配置config├── env.js├── jest│ ├── cssTransform.js│ └── fileTransform.js├── paths.js├── polyfills.js├── webpack.config.dev.js // 開發環境配置├── webpack.config.prod.js // 生產環境配置└── webpackDevServer.config.js複製代碼

好在CLI 3並無像CRA同樣,開發者你要是想本身修改配置,也是能夠的,我不須要你eject,你想改就去vue.config.js裏改吧。

若是你想看看默認的webpack配置,可執行vue inspect查看,默認狀況下,會將配置輸出到控制檯,你也能夠將結果指向一個文件,例如:vue inspect > webpack.config.js。

新特性到此就介紹完畢了。


參考資料

  • https://cli.vuejs.org/zh/guide/

  • https://npmjs.com/package/vue-cli

  • http://zhaozhiming.github.io/blog/2018/01/08/create-react-app-override-webpack-config/

  • https://segmentfault.com/a/1190000012581869#articleHeader5

  • http://www.css88.com/archives/8405

關於奇舞週刊

《奇舞週刊》是360公司專業前端團隊「奇舞團」運營的前端技術社區。關注公衆號後,直接發送連接到後臺便可給咱們投稿。

相關文章
相關標籤/搜索