99久久精品国产片-99久久精品国产免费-99久久精品国产麻豆-99久久精品国产国产毛片-99久久精品国产高清一区二区-99久久精品费精品国产一区二区

vue-cli3插件初體驗

2019-9-5    seo達(dá)人

vue-cli3發(fā)布自2018年8月,距離現(xiàn)在還不是特別久,最好搭建項目剛好用到,所以寫下這篇文章,記錄一下踩坑經(jīng)歷。

vue的作者說過,vue-cli的本質(zhì)是模

版的拉取,太多的配置導(dǎo)致了模版的難以維護(hù),所以重構(gòu)后的版本提供了插件的功能,一個插件對應(yīng)一個功能,這樣避免了多個模版,也使得cli維護(hù)性得到提高,這也是本篇文章的核心介紹內(nèi)容。

我對cli3的理解是,一方面擴(kuò)展了cli2的核心能力 ,一方面封裝了webpack邏輯和配置。在過去要去做一個cli,通常需要閱讀cli2的代碼,cli2的核心模塊分別是 generator,prompts,template,git-repo,并用同樣的方法去做一個cli,這樣其實成本不小,cli3的插件就是提供了這樣一種能力,你用他的規(guī)則,去做一個npm包,并發(fā)到倉庫,就可以獲得這種能力。

首先,先介紹一下vue-cli3,他的發(fā)布帶了哪些新功能呢?我總結(jié)一下,大概有以下5點:

1.功能豐富。這點相信大家都很好理解,他實在太好用了,模版里包含了大多數(shù)業(yè)界比較新的功能,可以一鍵集成typescripts等類型定義工具, eslint/tslint等語法檢驗工具,風(fēng)格規(guī)范,prettier,husky等格式化工具,還有postcss、pwa、vue-cli-server等等。

2.提高封裝性和擴(kuò)展性。這點指的是vue-cli-server,在過去webpack的邏輯和配置在項目里獨(dú)立維護(hù),各個項目之間就像孤島,vue-cli-server就像一個紐帶,連接起了各個項目,為項目升級webpack提供便利性,并且通過一份配置,提供個性化配置。

這里順帶扯一下vue.config.js, 這個東西就是用來個性化配置webpack的,他提供了很多的配置項,具體可以看官方文檔:

https://cli.vuejs.org/zh/config/

我們挑幾個常用的來講:

configureWebpack,這個幾乎是用的比較多的,簡單的方法,可以通過配置的方式配置,如下所示:

 
    
  1. module.exports = {
  2. configureWebpack: {
  3. plugins: [
  4. new MyAwesomeWebpackPlugin()
  5. ]
  6. }
  7. }復(fù)制代碼


這份配置,最終會被合并到原來的配置里,不會覆蓋。

復(fù)雜的方法,可以往這個字段傳一個函數(shù),如下所示:

 
  1. module.exports = {
  2. configureWebpack: config => {
  3. if (process.env.NODE_ENV === 'production') {
  4. // 為生產(chǎn)環(huán)境修改配置...
  5. } else {
  6. // 為開發(fā)環(huán)境修改配置...
  7. }
  8. }
  9. }復(fù)制代碼

這樣就可以在一個函數(shù)里做一些簡單的邏輯,config是webpack config,你可以直接修改config對象,也可以返回一個對象,這個對象最終也會被合并會webpack對象。

第三種方式,是通過webpack-chain來鏈?zhǔn)秸{(diào)用,代碼如下所示:

 
  1. module.exports = {
  2. chainWebpack: config => {
  3. config.module
  4. .rule('vue')
  5. .use('vue-loader')
  6. .loader('vue-loader')
  7. .tap(options => {
  8. // 修改它的選項...
  9. return options
  10. })
  11. }
  12. }復(fù)制代碼

3.提供圖形化管理界面,最所周知,gui易懂,cli,vue在降低學(xué)習(xí)門檻這方面,已經(jīng)是非常好了。

通過vue ui指令,可以查看編譯各個模塊的情況,模塊依賴情況,插件的情況,非常便于管理。

4.便捷性。vue-cli-server不僅支持項目的編譯,也支持單文件的編譯,具體的方法可以看官網(wǎng)介紹。

5.提供了cli的核心能力,也就是問詢,模版渲染,文件生成這幾大核心功能。具體的示意圖可以看如下:


以上是cli2的核心模塊,需要引用hbs,inquirer.js,metalsmit等基本模塊,cli3的插件機(jī)制基本幫我們封裝好了,我們只需要根據(jù)插件的規(guī)范,就可以獲取這種能力。

由于有的讀者可能對cli2的流程比較陌生,所以我想簡單描述一下cli2的工作流程,如下圖所示:


首先,cli2提供init指令,執(zhí)行這個指令,會去遠(yuǎn)程拿模版文件,并拉到本地用戶目錄的.vue-template的文件夾,然后通過meta里問題,去問你,然后生成最終模版到你執(zhí)行命令的目錄。

說完vue-cli2,我們來看看vue-cli3的插件是怎么樣的?

首先根據(jù)插件的位置,我們分成了cli插件,和service插件。cli的插件有完整的開發(fā)目錄,所能做的事情也比較多一點,service插件是一份js文件,導(dǎo)出一個函數(shù)。

cli插件的目錄如下所示:


具體的用發(fā)可以在官網(wǎng)了解到:

https://cli.vuejs.org/zh/dev-guide/plugin-dev.html#cli-%E6%8F%92%E4%BB%B6

那么他們是怎么工作的呢?

cli的代碼主要在@vue/cli 下面,他的大概的流程如下圖所示:


@vue/cli/bin/vue.js:

 
  1. program
  2. .command('add <plugin> [pluginOptions]')
  3. .description('install a plugin and invoke its generator in an already created project')
  4. .option('--registry <url>', 'Use specified npm registry when installing dependencies (only for npm)')
  5. .allowUnknownOption()
  6. .action((plugin) => {
  7. require('../lib/add')(plugin, minimist(process.argv.slice(3)))
  8. })
  9. program
  10. .command('invoke <plugin> [pluginOptions]')
  11. .description('invoke the generator of a plugin in an already created project')
  12. .option('--registry <url>', 'Use specified npm registry when installing dependencies (only for npm)')
  13. .allowUnknownOption()
  14. .action((plugin) => {
  15. require('../lib/invoke')(plugin, minimist(process.argv.slice(3)))
  16. })復(fù)制代碼

首先,執(zhí)行vue指令,會執(zhí)行@vue/cli/bin/vue.js,這里定義了vue add , vue invoke,vue build,vue serve,等指令,可以看出,add指令其實是包含invoke指令的,add指令主要是安裝一個包,并且觸發(fā)generator.js,invoke主要是觸發(fā)generator.js。

然后再來看@vue/cli/lib/add.js,

 
  1. const packageManager = loadOptions().packageManager || (hasProjectYarn(context) ? 'yarn' : 'npm')
  2. await installPackage(context, packageManager, options.registry, packageName)復(fù)制代碼
 
  1. const generatorPath = resolveModule(`${packageName}/generator`, context)
  2. if (generatorPath) {
  3. invoke(pluginName, options, context)
  4. } else {
  5. log(`Plugin ${packageName} does not have a generator to invoke`)
  6. }復(fù)制代碼

add.js主要安裝包,然后執(zhí)行invoke模塊,我們再看看invoke模塊做了什么。

@vue/cli/lib/invoke.js

 
    
  1. const generator = new Generator(context, {
  2. pkg,
  3. plugins: [plugin],
  4. files: await readFiles(context),
  5. completeCbs: createCompleteCbs,
  6. invoking: true
  7. })復(fù)制代碼

invoke里主要實例化generator類,然后把你的插件當(dāng)成參數(shù)傳給類,generator類算是vue-cli的核心類了。

@vue/cli/lib/generator.js

 
  1. plugins.forEach(({ id, apply, options }) => {
  2. const api = new GeneratorAPI(id, this, options, rootOptions)
  3. apply(api, options, rootOptions, invoking)
  4. })復(fù)制代碼

這個類主要負(fù)責(zé)執(zhí)行你的插件,然后把generatorapi作為參數(shù)傳入插件的generator.js導(dǎo)出的函數(shù)。

具體的vue-cli插件的開發(fā)是怎么樣的呢,我寫了一個demo,用在模擬多項目的ci模版管理,通常每個項目都有一份.gitlab-ci.yml模版,所以我們一般可以抽出一個公共的ci模版來管理,這里我用cli插件來管理,真正的項目可能不具備可行性,這里我只是用來寫一個例子。



目錄結(jié)構(gòu)大概如上所示,執(zhí)行vue add foo后,就會出現(xiàn)propmts對話框,然后選擇答案后,就會根據(jù)配置生成模版到你的根目錄下。


_gitlab-ci.yml ,根據(jù)問題選擇是否用私有npm倉庫:

 
  1. script:
  2. <%_ if (options.config === 'npm') { _%>
  3. - nrm add companynpm http://xxx.y.cn:XXXXX/
  4. - nrm use companynpm
  5. <%_ } _%>復(fù)制代碼

prompts.js,主要一些問題的設(shè)計:

 
  1. module.exports = [
  2. {
  3. name: 'config',
  4. type: 'list',
  5. message: `是否需要切換內(nèi)部源:`,
  6. choices: [
  7. {
  8. name: '需要',
  9. value: 'npm',
  10. short: ''
  11. },
  12. {
  13. name: '不需要',
  14. value: 'npm',
  15. short: ''
  16. }
  17. ]
  18. }
  19. ]復(fù)制代碼

generator.js 這個模塊很簡單,直接渲染模版

 
  1. module.exports = (api, options, rootOptions) => {
  2. // 復(fù)制并用 ejs 渲染 `./template` 內(nèi)所有的文件
  3. api.render('./template')
  4. }復(fù)制代碼

service插件主要放在項目本地,是一份js代碼,然后導(dǎo)出一個函數(shù),通過package.json配置指向這個js文件的路徑,


service主要依賴的代碼在@vue/cli-service里,首先先執(zhí)行@vue/cli-service/bin/vue-cli-service.js文件,


 
  1. const Service = require('../lib/Service')
  2. const service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())
  3. .....
  4. service.run(command, args, rawArgv).catch(err => {
  5. error(err)
  6. process.exit(1)
  7. })復(fù)制代碼

該文件實例化Service類,這個類是service插件的核心類,然后再執(zhí)行run方法。

再來看看@vue/cli-service/lib/Service.js的代碼:

首先構(gòu)造函數(shù)執(zhí)行resolvePlugin,把官方提供的插件和項目里的插件都加載進(jìn)來,

 
  1. constructor (context, { plugins, pkg, inlineOptions, useBuiltIn } = {}) {
  2. this.plugins = this.resolvePlugins(plugins, useBuiltIn)
  3. }復(fù)制代碼

resolvePlugin這個函數(shù)主要在這里引入本地的插件:

 
  1. resolvePlugins (inlinePlugins, useBuiltIn) {
  2. // Local plugins
  3. if (this.pkg.vuePlugins && this.pkg.vuePlugins.service) {
  4. const files = this.pkg.vuePlugins.service
  5. if (!Array.isArray(files)) {
  6. throw new Error(`Invalid type for option 'vuePlugins.service', expected 'array' but got ${typeof files}.`)
  7. }
  8. plugins = plugins.concat(files.map(file => ({
  9. id: `local:${file}`,
  10. apply: loadModule(file, this.pkgContext)
  11. })))
  12. }
  13. return plugins
  14. }復(fù)制代碼

run方法又會執(zhí)行init方法,在該方法內(nèi)部執(zhí)行插件:

 
  1. init (mode = process.env.VUE_CLI_MODE) {
  2. // apply plugins.
  3. this.plugins.forEach(({ id, apply }) => {
  4. apply(new PluginAPI(id, this), this.projectOptions)
  5. }
  6. }復(fù)制代碼


那么service插件要如何來實踐,我們來看如下的例子:

首先在package.json配置一下,指向本地的插件my-service.js

 
  1. "vuePlugins": {
  2. "service": [
  3. "my-service.js"
  4. ]
  5. }復(fù)制代碼

my-service.js的代碼如下所示:

 
  1. const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
  2. const webpack = require('webpack');
  3. module.exports = (api, projectOptions) => {
  4. api.registerCommand(
  5. 'analyze',
  6. {
  7. description: 'start analyze server',
  8. },
  9. (args) => {
  10. // 注冊 `vue-cli-service analyze`
  11. let options = projectOptions.pluginOptions.demoOptions
  12. console.log(options);
  13. // resolve webpack config
  14. const webpackConfig = api.resolveWebpackConfig();
  15. webpackConfig.plugins.push(new BundleAnalyzerPlugin());
  16. webpack(webpackConfig,(err,stats)=>{
  17. if(!err) console.log('打包成功')
  18. })
  19. },
  20. );
  21. };復(fù)制代碼

該插件主要擴(kuò)展vue-cli-service的指令,加了analyze指令,這個指令主要會向webpack的配置增加一個BundleAnalyzerPlugin的插件,用來分析包的大小,當(dāng)然,這里也是沒有太大的現(xiàn)實可行性的,vue-cli 提供了vue ui的Gui界面讓你看到打包后各個模塊的大小,或者cli的命令,vue-cli-service build --report,也能生一個報告,效果也是一樣。


至此,vue-cli和service插件的使用和實現(xiàn)都介紹完了,如果有哪里寫的不到位,希望各位大神能提出指正

日歷

鏈接

個人資料

藍(lán)藍(lán)設(shè)計的小編 http://www.lapeinture.cn

存檔

国产一区二区精品久久91| 欧美国产日韩一区二区三区| 超级乱淫黄漫画免费| 国产a视频| 九九免费高清在线观看视频| 国产不卡高清在线观看视频| 成人影院久久久久久影院| 国产亚洲精品aaa大片| 一级片片| 一级女性全黄生活片免费| 麻豆系列国产剧在线观看| 成人a大片高清在线观看| 欧美激情一区二区三区在线播放| 日韩免费片| 国产亚洲免费观看| 一本高清在线| 国产网站免费| 四虎论坛| 成人影视在线播放| 日本免费乱理伦片在线观看2018| 一本高清在线| 99热精品一区| 国产一区二区精品| 尤物视频网站在线观看| 日韩中文字幕一区二区不卡| 99热精品一区| 精品久久久久久中文| 欧美一级视| 日本在线不卡视频| 欧美电影免费| 四虎影视久久久免费| 欧美a级成人淫片免费看| 国产国语对白一级毛片| 午夜激情视频在线播放| 成人在免费观看视频国产| 欧美一级视频免费观看| 一级女人毛片人一女人| 精品在线视频播放| 国产91精品一区二区| 99色精品| 一级毛片视频在线观看| 日日日夜夜操| 香蕉视频三级| 日韩中文字幕在线观看视频| 免费一级生活片| 免费一级片网站| 国产精品12| 九九九在线视频| 国产网站免费视频| 韩国三级香港三级日本三级| 美女免费精品视频在线观看| 欧美a免费| 尤物视频网站在线| 日本乱中文字幕系列| 99久久精品国产高清一区二区| 一级片片| 青青青草影院| 精品国产一区二区三区久久久狼 | 久久99中文字幕| 欧美大片一区| 一本高清在线| 色综合久久天天综线观看| 999久久久免费精品国产牛牛| 九九精品影院| 97视频免费在线观看| 国产一区二区精品久久91| 国产国产人免费视频成69堂| 精品国产一区二区三区免费| 一级毛片视频免费| 精品视频在线观看视频免费视频| 毛片高清| 91麻豆精品国产自产在线| 欧美国产日韩精品| 黄视频网站免费| 欧美激情一区二区三区中文字幕| 日本在线不卡免费视频一区| 精品视频免费在线| 国产极品精频在线观看| 国产高清在线精品一区a| 国产网站麻豆精品视频| 国产视频一区二区在线播放| 国产一区二区精品久久| 久久国产影院| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 日韩免费在线观看视频| 日韩一级黄色片| 亚欧成人乱码一区二区| 一级女性全黄生活片免费| 精品在线观看一区| 国产a免费观看| 亚欧视频在线| 欧美另类videosbestsex高清| 日韩av成人| 99色精品| 国产综合成人观看在线| 日韩男人天堂| 国产福利免费观看| 国产国语在线播放视频| 日韩一级黄色| 久久成人亚洲| 欧美激情一区二区三区在线| 黄视频网站在线观看| 亚洲精品久久久中文字| 精品视频在线观看一区二区 | 国产不卡在线播放| 99色视频在线| 久久国产影院| 国产国语对白一级毛片| 久久国产影院| 国产伦理精品| 青草国产在线| 精品视频免费在线| 国产一级生活片| 国产精品1024永久免费视频| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 国产高清在线精品一区二区 | 亚欧成人毛片一区二区三区四区| 国产综合91天堂亚洲国产| 青青久久精品| 亚洲www美色| 四虎影视库| 精品久久久久久中文| 精品视频在线观看视频免费视频| 一本高清在线| 免费国产在线观看| 亚洲 男人 天堂| 成人高清视频免费观看| 日韩免费在线视频| 在线观看导航| 国产一区二区精品久久91| 欧美一级视频免费| 99热热久久| 亚洲精品影院| 午夜在线亚洲男人午在线| 九九久久99综合一区二区| 美女免费精品高清毛片在线视| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 国产原创视频在线| 黄色福利片| 沈樵在线观看福利| 国产伦理精品| 免费一级片网站| 九九精品久久久久久久久| 成人a大片高清在线观看| 精品国产香蕉在线播出 | 久久国产精品只做精品| 高清一级片| 美女免费黄网站| 免费毛片播放| 国产麻豆精品hdvideoss| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 欧美日本免费| 精品国产一区二区三区免费| 成人免费一级纶理片| 久久国产精品永久免费网站| 国产成人精品在线| 一级毛片视频免费| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 亚洲精品永久一区| 国产极品精频在线观看| 99热热久久| 高清一级片| 美女免费精品视频在线观看| 国产国语对白一级毛片| 国产伦久视频免费观看 视频 | 国产a网| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 高清一级片| 一本伊大人香蕉高清在线观看| 亚洲天堂一区二区三区四区| 99久久精品国产国产毛片| 久久福利影视| 国产一区二区高清视频| 国产一区二区福利久久| 国产视频一区在线| 中文字幕Aⅴ资源网| 精品视频在线观看一区二区 | 欧美a级成人淫片免费看| 国产精品1024永久免费视频| 欧美激情在线精品video| 台湾毛片| 午夜家庭影院| 日本免费看视频| 深夜做爰性大片中文| 国产网站在线| 亚欧乱色一区二区三区| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 欧美a级成人淫片免费看| 九九九国产| 精品视频在线看 | 国产成人啪精品| 麻豆系列 在线视频| 一级毛片视频播放| 成人在激情在线视频| 精品在线观看一区| 尤物视频网站在线| 久久久久久久久综合影视网| 国产福利免费视频| 超级乱淫黄漫画免费| 久久99爰这里有精品国产|