目錄
github位址(內含簡單範例)
使用技術堆疊
#需要學習的知識
6. alias vue指向问题
7. devServer的使用
8. 热重载原理
9. localtunnel的使用
首頁 web前端 js教程 vue專案腳手架介紹

vue專案腳手架介紹

Jun 26, 2017 am 10:52 AM
web 簡單 鷹架 專案

github位址(內含簡單範例)

使用技術堆疊

  • #webpack(^2.6.1)

  • webpack-dev-server(^2.4.5)

  • vue(^2.3.3)

  • vuex(^2.3 .1)

  • vue-router(^2.5.3)

  • vue-loader(^12.2.1)

  • eslint(^3.19.0)

#需要學習的知識

##vue.js 

vuex 
vue -router 
vue-loader 
webpack2 
eslint 

內容相當多,尤其是webpack2教程,官方腳手架vue-cli雖然相當齊全,但是修改起來還是挺花時間,於是自己參照網路上的資料和之前做過的專案用到的建構工具地去寫了一個簡單vue專案鷹架。適用於多頁面spa模式的業務場景(每個模組都是一個spa)。比較簡單,主要就是一個webpack.config.js文件,沒有說刻意去分割成分webpack.dev.config.js、webpack.prov.config.js等等。以下是整個webpack.config.js檔案程式碼:

  1 const { resolve } = require('path')  2 const webpack = require('webpack')  3 const HtmlWebpackPlugin = require('html-webpack-plugin')  4 const ExtractTextPlugin = require('extract-text-webpack-plugin')  5 const glob = require('glob')  6   7 module.exports = (options = {}) => {  8     // 配置文件,根据 run script不同的config参数来调用不同config  9     const config = require('./config/' + (process.env.npm_config_config || options.config || 'dev')) 10     // 遍历入口文件,这里入口文件与模板文件名字保持一致,保证能同时合成HtmlWebpackPlugin数组和入口文件数组 11     const entries = glob.sync('./src/modules/*.js') 12     const entryJsList = {} 13     const entryHtmlList = [] 14     for (const path of entries) { 15         const chunkName = path.slice('./src/modules/'.length, -'.js'.length) 16         entryJsList[chunkName] = path 17         entryHtmlList.push(new HtmlWebpackPlugin({ 18             template: path.replace('.js', '.html'), 19             filename: 'modules/' + chunkName + '.html', 20             chunks: ['manifest', 'vendor', chunkName] 21         })) 22     } 23     // 处理开发环境和生产环境ExtractTextPlugin的使用情况 24     function cssLoaders(loader, opt) { 25         const loaders = loader.split('!') 26         const opts = opt || {} 27         if (options.dev) { 28             if (opts.extract) { 29                 return loader 30             } else { 31                 return loaders 32             } 33         } else { 34             const fallbackLoader = loaders.shift() 35             return ExtractTextPlugin.extract({ 36                 use: loaders, 37                 fallback: fallbackLoader 38             }) 39         } 40     } 41  42     const webpackObj = { 43         entry: Object.assign({ 44             vendor: ['vue', 'vuex', 'vue-router'] 45         }, entryJsList), 46         // 文件内容生成哈希值chunkhash,使用hash会更新所有文件 47         output: { 48             path: resolve(__dirname, 'dist'), 49             filename: options.dev ? 'static/js/[name].js' : 'static/js/[name].[chunkhash].js', 50             chunkFilename: 'static/js/[id].[chunkhash].js', 51             publicPath: config.publicPath 52         }, 53  54         externals: { 55  56         }, 57  58         module: { 59             rules: [ 60                 // 只 lint 本地 *.vue 文件,需要安装eslint-plugin-html,并配置eslintConfig(package.json) 61                 { 62                     enforce: 'pre', 63                     test: /.vue$/, 64                     loader: 'eslint-loader', 65                     exclude: /node_modules/ 66                 }, 67                 /* 68                      69                      70                     [eslint资料] 71                  */ 72                 { 73                     test: /\.js$/, 74                     exclude: /node_modules/, 75                     use: ['babel-loader', 'eslint-loader'] 76                 }, 77                 // 需要安装vue-template-compiler,不然编译报错 78                 { 79                     test: /\.vue$/, 80                     loader: 'vue-loader', 81                     options: { 82                         loaders: { 83                             sass: cssLoaders('vue-style-loader!css-loader!sass-loader', { extract: true }) 84                         } 85                     } 86                 }, 87                 { 88                     // 需要有相应的css-loader,因为第三方库可能会有文件 89                     // (如:element-ui) css在node_moudle 90                     // 生产环境才需要code抽离,不然的话,会使热重载失效 91                     test: /\.css$/, 92                     use: cssLoaders('style-loader!css-loader') 93                 }, 94                 { 95                     test: /\.(scss|sass)$/, 96                     use: cssLoaders('style-loader!css-loader!sass-loader') 97                 }, 98                 { 99                     test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,100                     use: [101                         {102                             loader: 'url-loader',103                             options: {104                                 limit: 10000,105                                 name: 'static/imgs/[name].[ext]?[hash]'106                             }107                         }108                     ]109                 }110             ]111         },112 113         plugins: [114             ...entryHtmlList,115             // 抽离css116             new ExtractTextPlugin({117                 filename: 'static/css/[name].[chunkhash].css',118                 allChunks: true119             }),120             // 抽离公共代码121             new webpack.optimize.CommonsChunkPlugin({122                 names: ['vendor', 'manifest']123             }),124             // 定义全局常量125             // cli命令行使用process.env.NODE_ENV不如期望效果,使用不了,所以需要使用DefinePlugin插件定义,定义形式'"development"'或JSON.stringify('development')126             new webpack.DefinePlugin({127                 'process.env': {128                     NODE_ENV: options.dev ? JSON.stringify('development') : JSON.stringify('production')129                 }130             })131 132         ],133 134         resolve: {135             // require时省略的扩展名,不再需要强制转入一个空字符串,如:require('module') 不需要module.js136             extensions: ['.js', '.json', '.vue', '.scss', '.css'],137             // require路径简化138             alias: {139                 '~': resolve(__dirname, 'src'),140                 // Vue 最早会打包生成三个文件,一个是 runtime only 的文件 vue.common.js,一个是 compiler only 的文件 compiler.js,一个是 runtime + compiler 的文件 vue.js。141                 // vue.js = vue.common.js + compiler.js,默认package.json的main是指向vue.common.js,而template 属性的使用一定要用compiler.js,因此需要在alias改变vue指向142                 vue: 'vue/dist/vue'143             },144             // 指定import从哪个目录开始查找145             modules: [146                 resolve(__dirname, 'src'),147                 'node_modules'148             ]149         },150         // 开启http服务,publicPath => 需要与Output保持一致 || proxy => 反向代理 || port => 端口号151         devServer: config.devServer ? {152             port: config.devServer.port,153             proxy: config.devServer.proxy,154             publicPath: config.publicPath,155             stats: { colors: true }156         } : undefined,157         // 屏蔽文件超过限制大小的warn158         performance: {159             hints: options.dev ? false : 'warning'160         },161         // 生成devtool,保证在浏览器可以看到源代码,生产环境设为false162         devtool: 'inline-source-map'163     }164 165     if (!options.dev) {166         webpackObj.devtool = false167         webpackObj.plugins = (webpackObj.plugins || []).concat([168             // 压缩js169             new webpack.optimize.UglifyJsPlugin({170                 // webpack2,默认为true,可以不用设置171                 compress: {172                     warnings: false173                 }174             }),175             //  压缩 loaders176             new webpack.LoaderOptionsPlugin({177                 minimize: true178             })179         ])180     }181 182     return webpackObj183 }
登入後複製
 

上面的程式碼對於每個組態項目都有註解說明,這裡有幾點要注意的:

1. webpack.config.js導出的是一個function

之前專案的webpack.config.js是以物件形式export的,如下

1 module.exports = {2     entry: ...,3     output: {4         ...5     },6     ...7 }
登入後複製
而現在倒出來的是一個function,如下:

1 module.exports = (options = {}) => { 
2     return {3         entry: ...,4         output: {5             ...6         },7         ...8     }9 }
登入後複製
#這樣的話,function會在執行webpack CLI的時候取得webpack的參數,透過options傳入function,看一下package.json:

1     "local": "npm run dev --config=local",2     "dev": "webpack-dev-server -d --hot --inline --env.dev --env.config dev",3     "build": "rimraf dist && webpack -p --env.config prod" //rimraf清空dist目录
登入後複製
對於

local指令,我們執行的是dev指令,但在最後面會- -config=local,這是配置,這樣我們可以透過process.env.npm_config_config取得到,而對於dev命令,對於--env XXX,我們可以在function取得option.config= 'dev' 和 option.dev= true的值,特別方便!以此便可以同步參數來載入不同的設定檔了。對於-d-p不清楚的話,可以這裡查看,很詳細!

1     // 配置文件,根据 run script不同的config参数来调用不同config2     const config = require('./config/' + (process.env.npm_config_config || options.config || 'dev'))
登入後複製
2. modules放置模板檔案、入口檔案、對應模組的vue檔案

將入口檔案和範本檔案放到modules目錄(名字保持一致), webpack檔案會透過glob讀取modules目錄,遍歷產生入口檔案物件和模板檔案數組,如下:

 1     const entries = glob.sync('./src/modules/*.js') 2     
 const entryJsList = {} 3     const entryHtmlList = [] 4     
 for (const path of entries) { 5         const chunkName = path.slice('./src/modules/'.length, -'.js'.length) 6         
 entryJsList[chunkName] = path 7         entryHtmlList.push(new HtmlWebpackPlugin({ 8             
 template: path.replace('.js', '.html'), 9             filename: 'modules/' + chunkName + '.html',10             
 chunks: ['manifest', 'vendor', chunkName]11         }))12     }
登入後複製
對於HtmlWebpackPlugin外掛程式中幾個設定項的意思是,template:模板路徑,filename:檔案名稱,這裡為了區分開來模板檔案我是放置在dist/modules資料夾中,而對應的編譯打包好的js、img(對於圖片我們是使用file-loader、url-loader進行抽離,對於這兩個不是很理解的,可以看這裡)、css我也是會放在dist/下對應目錄的,這樣目錄會比較清晰。 chunks:指定插入檔案中的chunk,後面我們會產生manifest檔案、公共vendor、以及對應產生的jscss(名稱一樣)

3. 處理開發環境和生產環境ExtractTextPlugin的使用情況

開發環境,不需要把css進行抽離,要以style插入html檔案中,可以很好實現熱替換 生產環境,需要把css進行抽離合併,如下(根據options.dev區分開發和生產):

 1     // 处理开发环境和生产环境ExtractTextPlugin的使用情况 2    
  function cssLoaders(loader, opt) { 3         const loaders = loader.split('!') 4         
  const opts = opt || {} 5         if (options.dev) { 6             if (opts.extract) { 7                 
  return loader 8             } else { 9                 return loaders10             }11         }
  else {12             const fallbackLoader = loaders.shift()13             
  return ExtractTextPlugin.extract({14                 use: loaders,15                 
  fallback: fallbackLoader16             })17         }18     }19     ...20     // 使用情况21    
   // 注意:需要安装vue-template-compiler,不然编译会报错22     {23         test: /\.vue$/,24         
   loader: 'vue-loader',25         options: {26             loaders: {27                 
   sass: cssLoaders('vue-style-loader!css-loader!sass-loader', { extract: true })28             }         
   }30     },31     ...32     {33         test: /\.(scss|sass)$/,34       
   use: cssLoaders('style-loader!css-loader!sass-loader')35     }
登入後複製
再使用ExtractTextPlugin合併抽離到

static/css/目錄

4. 定義全域常數

#cli指令行(

webpack -p)使用process.env.NODE_ENV不如期望效果,使用不了,所以需要使用DefinePlugin外掛定義,定義形式'"development"'或JSON.stringify(process.env.NODE_ENV) ,我使用這樣的寫法'development',結果報錯(針對webpack2),查找了一下網上資料,它是這樣講的,可以去看一下,設置如下:

1     new webpack.DefinePlugin({2         'process.env': {3            
 NODE_ENV: options.dev ? JSON.stringify('development') : JSON.stringify('production')4         
 }5    
 })
登入後複製
# 5. 使用eslint修正程式碼規範

透過eslint檢查程式碼的規範性,透過定義一套設定項,來規範程式碼,這樣多人協作,寫出來的程式碼也會比較優雅,不好的地方是,就是設定項目太多,有些預設項目設定我們不需要,但是確是處處限制我們,需要透過設定來屏蔽掉,可以透過

.eslintrc 檔案或是package.json的 eslintConfig,還有其他方式,可以到中文網看,這裡我用的是package.json方式,如下:

 1     ... 2   "eslintConfig": { 3     "parser": "babel-eslint", 4     "extends": "enough", 5    
  "env": { 6       "browser": true, 7       "node": true, 8       "commonjs": true, 9       "es6": true10     },
  11     "rules": {12       "linebreak-style": 0,13       "indent": [2, 4],14       "no-unused-vars": 0,15      
   "no-console": 016     },17     "plugins": [18       "html"19     ]20   },21   ...
登入後複製

我们还需要安装 npm install eslint eslint-config-enough eslint-loader --save-dev,eslint-config-enough是所谓的配置文件,这样package.json的内容才能起效,但是不当当是这样,对应编辑器也需要安装对应的插件,sublime text 3需要安装SublimeLinter、SublimeLinter-contrib-eslint插件。对于所有规则的详解,可以去看官网,也可以去这里看,很详细!
由于我们使用的是vue-loader,自然我们是希望能对.vue文件eslint,那么需要安装eslint-plugin-html,在package.json中进行配置。然后对应webpack配置:

1     {2         enforce: 'pre',3         test: /.vue$/,4         loader: 'eslint-loader',5       
  exclude: /node_modules/6     }
登入後複製

我们会发现webpack v1和v2之间会有一些不同,比如webpack1对于预先加载器处理的执行是这样的,

1   module: {2     preLoaders: [3       {4         test: /\.js$/,5        
 loader: "eslint-loader"6       
}7     ]8   }
登入後複製

更多的不同可以到中文网看,很详细,不做拓展。

6. alias vue指向问题

1     ...2     alias: {3        
 vue: 'vue/dist/vue'4     },
 5     ...
登入後複製

Vue 最早会打包生成三个文件,一个是 runtime only 的文件 vue.common.js,一个是 compiler only 的文件 compiler.js,一个是 runtime + compiler 的文件 vue.js。vue.js = vue.common.js + compiler.js,默认package.json的main是指向vue.common.js,而template 属性的使用一定要用compiler.js,因此需要在alias改变vue指向

7. devServer的使用

之前的项目中使用的是用express启动http服务,webpack-dev-middleware+webpack-hot-middleware,这里会用到compiler+compilation,这个是webpack的编译器和编译过程的一些知识,也不是很懂,后续要去做做功课,应该可以加深对webpack运行机制的理解。这样做的话,感觉复杂很多,对于webpack2.0 devServer似乎功能更强大更加完善了,所以直接使用就可以了。如下:

 1     devServer: { 2         port: 8080, //端口号 3        
  proxy: { //方向代理 /api/auth/ => http://api.example.dev 4             '/api/auth/': { 5                 
  target: 'http://api.example.dev', 6                 changeOrigin: true, 7                 
  pathRewrite: { '^/api': '' } 8             } 9         },10         
  publicPath: config.publicPath,11         stats: { colors: true }12     }13     
  //changeOrigin会修改HTTP请求头中的Host为target的域名, 这里会被改为api.example.dev14     
  //pathRewrite用来改写URL, 这里我们把/api前缀去掉,直接使用/auth/请求
登入後複製

webpack 2 打包实战讲解得非常好,非常棒。可以去看一下,一定会有所收获!

8. 热重载原理

webpack中文网,讲的还算清楚,不过可能太笨,看起来还是云里雾里的,似懂非懂的,补补课,好好看看。

9. localtunnel的使用

Localtunnel 是一个可以让内网服务器暴露到公网上的开源项目,使用可以看这里,

1 $ npm install -g localtunnel2 $ lt --port 80803 your url is: https://uhhzexcifv.localtunnel.me
登入後複製

这样的话,可以把我们的本地网站暂时性地暴露到公网,可以对网站做一些线上线下对比,详细内容可以去了解一下localtunnel,这里讲的是通过上面配置,访问https://uhhzexcifv.localtunnel.me,没有达到理想效果,出现了Invalid Host header的错误,因为devServer缺少一个配置disableHostCheck: true,这样的一个配置,很多文档上面都没有说明,字面上面的意思不要去检查Host,这样设置,便可以绕过这一层检验,设置的配置项在optionsSchema.json中,issue可以看这里

文章内容可能会更新,可以关注github

以上是vue專案腳手架介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1422
52
Laravel 教程
1316
25
PHP教程
1267
29
C# 教程
1239
24
最簡單的硬碟序號查詢方式 最簡單的硬碟序號查詢方式 Feb 26, 2024 pm 02:24 PM

硬碟序號是硬碟的一個重要標識,通常用於唯一標識硬碟以及進行硬體識別。在某些情況下,我們可能需要查詢硬碟序號,例如在安裝作業系統、尋找正確裝置驅動程式或進行硬碟維修等情況下。本文將介紹一些簡單的方法,幫助大家查詢硬碟序號。方法一:使用Windows命令提示字元開啟命令提示字元。在Windows系統中,按下Win+R鍵,輸入"cmd"並按下回車鍵即可開啟命

AI攻克費馬大定理?數學家放棄5年職業生涯,將100頁證明變代碼 AI攻克費馬大定理?數學家放棄5年職業生涯,將100頁證明變代碼 Apr 09, 2024 pm 03:20 PM

費馬大定理,即將被AI攻克?而整件事最有意義的地方在於,AI即將解決的費馬大定理,正是為了證明AI無用。曾經,數學屬於純粹的人類智力王國;如今,這片疆土正被先進的演算法所破解,所踐踏。圖片費馬大定理,是一個「臭名昭著」的謎題,在幾個世紀以來,一直困擾著數學家。它在1993年被證明,而現在,數學家們有一個偉大計畫:用電腦把證明過程重現。他們希望在這個版本的證明中,如果有任何邏輯上的錯誤,都可以由電腦檢查出來。專案網址:https://github.com/riccardobrasca/flt

分享PyCharm專案打包的簡易方法 分享PyCharm專案打包的簡易方法 Dec 30, 2023 am 09:34 AM

簡單易懂的PyCharm專案打包方法分享隨著Python的流行,越來越多的開發者使用PyCharm作為Python開發的主要工具。 PyCharm是功能強大的整合開發環境,它提供了許多方便的功能來幫助我們提高開發效率。其中一個重要的功能就是專案的打包。本文將介紹如何在PyCharm中簡單易懂地打包項目,並提供具體的程式碼範例。為什麼要打包專案?在Python開發

PyCharm實用技巧:將項目轉換為可執行EXE文件 PyCharm實用技巧:將項目轉換為可執行EXE文件 Feb 23, 2024 am 09:33 AM

PyCharm是一款功能強大的Python整合開發環境,提供了豐富的開發工具和環境配置,讓開發者更有效率地編寫和除錯程式碼。在使用PyCharm進行Python專案開發的過程中,有時候我們需要將專案打包成可執行的EXE文件,以便在沒有安裝Python環境的電腦上執行。本文將介紹如何使用PyCharm將專案轉換為可執行的EXE文件,同時給出具體的程式碼範例。首

深入了解PyCharm:快速刪除項目的方法 深入了解PyCharm:快速刪除項目的方法 Feb 26, 2024 pm 04:21 PM

標題:深入了解PyCharm:刪除專案的高效方式近年來,Python作為一種強大而靈活的程式語言,受到越來越多開發者的青睞。在Python專案的開發中,選擇一個高效的整合開發環境至關重要。 PyCharm作為一款功能強大的整合開發環境,為Python開發者提供了許多便利的功能和工具,其中包括快速、有效率地刪除專案目錄。以下將著重介紹如何使用PyCharm中的刪除

如何使用Java來寫一個簡單的學生成績報表產生器? 如何使用Java來寫一個簡單的學生成績報表產生器? Nov 03, 2023 pm 02:57 PM

如何使用Java來寫一個簡單的學生成績報表產生器?學生成績報表產生器是可以幫助老師或教育者快速產生學生成績報告的工具。本文將介紹如何使用Java來撰寫簡單的學生成績報表產生器。首先,我們要定義學生對象和學生成績對象。學生對象包含學生的姓名、學號等基本訊息,而學生成績對象則包含學生的科目成績和平均成績等資訊。以下是一個簡單的學生物件的定義:public

如何透過C++寫一個簡單的掃雷遊戲? 如何透過C++寫一個簡單的掃雷遊戲? Nov 02, 2023 am 11:24 AM

如何透過C++寫一個簡單的掃雷遊戲?掃雷遊戲是一款經典的益智類遊戲,它要求玩家根據已知的雷區佈局,在沒有踩到地雷的情況下,揭示所有的方塊。在這篇文章中,我們將介紹如何使用C++來寫一個簡單的掃雷遊戲。首先,我們需要定義一個二維陣列來表示掃雷遊戲的地圖。數組中的每個元素可以是一個結構體,用於儲存方塊的狀態,例如是否揭示、是否有雷等資訊。另外,我們還需要定義

如何透過C++寫一個簡單的音樂推薦系統? 如何透過C++寫一個簡單的音樂推薦系統? Nov 03, 2023 pm 06:45 PM

如何透過C++寫一個簡單的音樂推薦系統?引言:音樂推薦系統是現代資訊科技的研究熱點,它可以根據使用者的音樂偏好和行為習慣,向使用者推薦符合其口味的歌曲。本文將介紹如何使用C++來寫一個簡單的音樂推薦系統。一、收集用戶資料首先,我們需要收集用戶的音樂偏好資料。可以透過線上調查、問卷調查等方式來獲得使用者對不同類型音樂的喜好程度。將資料保存在一個文字檔案或資料庫

See all articles