国产精品爱久久久久久久小说,女人扒开腿让男人桶到爽 ,亚洲欧美国产双大乳头,国产成人精品综合久久久久,国产精品制服丝袜无码,免费无码精品黄av电影,黑色丝袜无码中中文字幕,乱熟女高潮一区二区在线

    vue-cli3插件初體驗

    2019-9-5    seo達人

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

    vue的作者說過,vue-cli的本質是模

    版的拉取,太多的配置導致了模版的難以維護,所以重構后的版本提供了插件的功能,一個插件對應一個功能,這樣避免了多個模版,也使得cli維護性得到提高,這也是本篇文章的核心介紹內容。

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

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

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

    2.提高封裝性和擴展性。這點指的是vue-cli-server,在過去webpack的邏輯和配置在項目里獨立維護,各個項目之間就像孤島,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. }復制代碼


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

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

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

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

    第三種方式,是通過webpack-chain來鏈式調用,代碼如下所示:

     
    
    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. }復制代碼

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

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

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

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


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

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


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

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

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

    cli插件的目錄如下所示:


    具體的用發可以在官網了解到:

    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. })復制代碼

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

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

     
    
    1. const packageManager = loadOptions().packageManager || (hasProjectYarn(context) ? 'yarn' : 'npm')
    2. await installPackage(context, packageManager, options.registry, packageName)復制代碼
     
    
    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. }復制代碼

    add.js主要安裝包,然后執行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. })復制代碼

    invoke里主要實例化generator類,然后把你的插件當成參數傳給類,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. })復制代碼

    這個類主要負責執行你的插件,然后把generatorapi作為參數傳入插件的generator.js導出的函數。

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



    目錄結構大概如上所示,執行vue add foo后,就會出現propmts對話框,然后選擇答案后,就會根據配置生成模版到你的根目錄下。


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

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

    prompts.js,主要一些問題的設計:

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

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

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

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


    service主要依賴的代碼在@vue/cli-service里,首先先執行@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. })復制代碼

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

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

    首先構造函數執行resolvePlugin,把官方提供的插件和項目里的插件都加載進來,

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

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

     
    
    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. }復制代碼

    run方法又會執行init方法,在該方法內部執行插件:

     
    
    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. }復制代碼


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

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

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

    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. };復制代碼

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


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

    日歷

    鏈接

    個人資料

    藍藍設計的小編 http://m.dzxscac.cn

    存檔

    主站蜘蛛池模板: 一级黄色片免费看| 800av在线视频| 三级特黄60分钟在线播放 | 久草一区二区| 亚洲国产欧美在线成人| 国产免费啪嗒啪嗒视频看看| 日韩激情久久| 色视频导航| 欧美精品videosbestsex日本 | 精品久久伊人| 国产suv精品一区二区| 国产精品无码综合区| youjizzxxxxx| 欧产日产国产69| 国产成人小视频| 国产亚洲日韩在线一区二区三区 | 九色porny丨自拍视频| 福利片在线观看| 中文在线免费视频| 精品一区二区三区三区| 国产剧情麻豆女教师在线观看 | 日本一区二区视频在线| 亚洲综合色网一区二区三区| 无码中文av波多野吉衣迅雷下载| 亚洲另类国产综合小说| 大粗鳮巴久久久久久久久| 影音先锋2020色资源网| 日韩精品人妻系列无码专区免费 | 色伦专区97中文字幕| av无码免费岛国动作片不卡| 国产在线一区二区| 人人干人| 蜜臀在线播放一区在线播放| 一区二区三区在线 | 网站| 欧美成人乱码一二三四区 | 亚洲天天堂天堂激情性色| 不满足出轨的人妻中文字幕| 国内精品久久久久影院嫩草| 91久久爱| 中文字幕无码免费久久| 欧美精品18videos性欧美|