摘要:簡單項目腳手架地址使用技術棧需要學習的知識內容相當多,尤其是教程,官方腳手架雖然相當完整齊全,但是修改起來還是挺花時間,于是自己參照網上的資料和之前做過的項目用到的構建工具地去寫了一個簡單項目腳手架。
簡單vue項目腳手架 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模式的業(yè)務場景(每個模塊都是一個spa)。比較簡單,主要就是一個webpack.config.js文件,沒有說特意地去劃分成分webpack.dev.config.js、webpack.prov.config.js等等。下面是整個webpack.config.js文件代碼:
const { resolve } = require("path") const webpack = require("webpack") const HtmlWebpackPlugin = require("html-webpack-plugin") const ExtractTextPlugin = require("extract-text-webpack-plugin") const glob = require("glob") module.exports = (options = {}) => { // 配置文件,根據 run script不同的config參數來調用不同config const config = require("./config/" + (process.env.npm_config_config || options.config || "dev")) // 遍歷入口文件,這里入口文件與模板文件名字保持一致,保證能同時合成HtmlWebpackPlugin數組和入口文件數組 const entries = glob.sync("./src/modules/*.js") const entryJsList = {} const entryHtmlList = [] for (const path of entries) { const chunkName = path.slice("./src/modules/".length, -".js".length) entryJsList[chunkName] = path entryHtmlList.push(new HtmlWebpackPlugin({ template: path.replace(".js", ".html"), filename: "modules/" + chunkName + ".html", chunks: ["manifest", "vendor", chunkName] })) } // 處理開發(fā)環(huán)境和生產環(huán)境ExtractTextPlugin的使用情況 function cssLoaders(loader, opt) { const loaders = loader.split("!") const opts = opt || {} if (options.dev) { if (opts.extract) { return loader } else { return loaders } } else { const fallbackLoader = loaders.shift() return ExtractTextPlugin.extract({ use: loaders, fallback: fallbackLoader }) } } const webpackObj = { entry: Object.assign({ vendor: ["vue", "vuex", "vue-router"] }, entryJsList), // 文件內容生成哈希值chunkhash,使用hash會更新所有文件 output: { path: resolve(__dirname, "dist"), filename: options.dev ? "static/js/[name].js" : "static/js/[name].[chunkhash].js", chunkFilename: "static/js/[id].[chunkhash].js", publicPath: config.publicPath }, externals: { }, module: { rules: [ // 只 lint 本地 *.vue 文件,需要安裝eslint-plugin-html,并配置eslintConfig(package.json) { enforce: "pre", test: /.vue$/, loader: "eslint-loader", exclude: /node_modules/ }, /* http://blog.guowenfh.com/2016/08/07/ESLint-Rules/ http://eslint.cn/docs/user-guide/configuring [eslint資料] */ { test: /.js$/, exclude: /node_modules/, use: ["babel-loader", "eslint-loader"] }, // 需要安裝vue-template-compiler,不然編譯報錯 { test: /.vue$/, loader: "vue-loader", options: { loaders: { sass: cssLoaders("vue-style-loader!css-loader!sass-loader", { extract: true }) } } }, { // 需要有相應的css-loader,因為第三方庫可能會有文件 // (如:element-ui) css在node_moudle // 生產環(huán)境才需要code抽離,不然的話,會使熱重載失效 test: /.css$/, use: cssLoaders("style-loader!css-loader") }, { test: /.(scss|sass)$/, use: cssLoaders("style-loader!css-loader!sass-loader") }, { test: /.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(?.+)?$/, use: [ { loader: "url-loader", options: { limit: 10000, name: "static/imgs/[name].[ext]?[hash]" } } ] } ] }, plugins: [ ...entryHtmlList, // 抽離css new ExtractTextPlugin({ filename: "static/css/[name].[chunkhash].css", allChunks: true }), // 抽離公共代碼 new webpack.optimize.CommonsChunkPlugin({ names: ["vendor", "manifest"] }), // 定義全局常量 // cli命令行使用process.env.NODE_ENV不如期望效果,使用不了,所以需要使用DefinePlugin插件定義,定義形式""development""或JSON.stringify("development") new webpack.DefinePlugin({ "process.env": { NODE_ENV: options.dev ? JSON.stringify("development") : JSON.stringify("production") } }) ], resolve: { // require時省略的擴展名,不再需要強制轉入一個空字符串,如:require("module") 不需要module.js extensions: [".js", ".json", ".vue", ".scss", ".css"], // require路徑簡化 alias: { "~": resolve(__dirname, "src"), // 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指向 vue: "vue/dist/vue" }, // 指定import從哪個目錄開始查找 modules: [ resolve(__dirname, "src"), "node_modules" ] }, // 開啟http服務,publicPath => 需要與Output保持一致 || proxy => 反向代理 || port => 端口號 devServer: config.devServer ? { port: config.devServer.port, proxy: config.devServer.proxy, publicPath: config.publicPath, stats: { colors: true } } : undefined, // 屏蔽文件超過限制大小的warn performance: { hints: options.dev ? false : "warning" }, // 生成devtool,保證在瀏覽器可以看到源代碼,生產環(huán)境設為false devtool: "inline-source-map" } if (!options.dev) { webpackObj.devtool = false webpackObj.plugins = (webpackObj.plugins || []).concat([ // 壓縮js new webpack.optimize.UglifyJsPlugin({ // webpack2,默認為true,可以不用設置 compress: { warnings: false } }), // 壓縮 loaders new webpack.LoaderOptionsPlugin({ minimize: true }) ]) } return webpackObj }上面的代碼對于每個配置項都有注釋說明,這里有幾點需要注意的: 1. webpack.config.js導出的是一個function
之前項目的webpack.config.js是以對象形式export的,如下
module.exports = { entry: ..., output: { ... }, ... }
而現在倒出來的是一個function,如下:
module.exports = (options = {}) => { return { entry: ..., output: { ... }, ... } }
這樣的話,function會在執(zhí)行webpack CLI的時候獲取webpack的參數,通過options傳進function,看一下package.json:
"local": "npm run dev --config=local", "dev": "webpack-dev-server -d --hot --inline --env.dev --env.config dev", "build": "rimraf dist && webpack -p --env.config prod" //rimraf清空dist目錄
對于local命令,我們執(zhí)行的是dev命令,但是在最后面會--config=local,這是配置,這樣我們可以通過process.env.npm_config_config獲取到,而對于dev命令,對于--env XXX,我們便可以在function獲取option.config= "dev" 和 option.dev= true的值,特別方便!以此便可以同步參數來加載不同的配置文件了。對于-d、-p不清楚的話,可以這里查看,很詳細!
// 配置文件,根據 run script不同的config參數來調用不同config const config = require("./config/" + (process.env.npm_config_config || options.config || "dev"))2. modules放置模板文件、入口文件、對應模塊的vue文件
將入口文件和模板文件放到modules目錄(名字保持一致),webpack文件會通過glob讀取modules目錄,遍歷生成入口文件對象和模板文件數組,如下:
const entries = glob.sync("./src/modules/*.js") const entryJsList = {} const entryHtmlList = [] for (const path of entries) { const chunkName = path.slice("./src/modules/".length, -".js".length) entryJsList[chunkName] = path entryHtmlList.push(new HtmlWebpackPlugin({ template: path.replace(".js", ".html"), filename: "modules/" + chunkName + ".html", chunks: ["manifest", "vendor", chunkName] })) }
對于HtmlWebpackPlugin插件中幾個配置項的意思是,template:模板路徑,filename:文件名稱,這里為了區(qū)分開來模板文件我是放置在dist/modules文件夾中,而對應的編譯打包好的js、img(對于圖片我們是使用file-loader、url-loader進行抽離,對于這兩個不是很理解的,可以看這里)、css我也是會放在dist/下對應目錄的,這樣目錄會比較清晰。chunks:指定插入文件中的chunk,后面我們會生成manifest文件、公共vendor、以及對應生成的jscss(名稱一樣)
3. 處理開發(fā)環(huán)境和生產環(huán)境ExtractTextPlugin的使用情況開發(fā)環(huán)境,不需要把css進行抽離,要以style插入html文件中,可以很好實現熱替換
生產環(huán)境,需要把css進行抽離合并,如下(根據options.dev區(qū)分開發(fā)和生產):
// 處理開發(fā)環(huán)境和生產環(huán)境ExtractTextPlugin的使用情況 function cssLoaders(loader, opt) { const loaders = loader.split("!") const opts = opt || {} if (options.dev) { if (opts.extract) { return loader } else { return loaders } } else { const fallbackLoader = loaders.shift() return ExtractTextPlugin.extract({ use: loaders, fallback: fallbackLoader }) } } ... // 使用情況 // 注意:需要安裝vue-template-compiler,不然編譯會報錯 { test: /.vue$/, loader: "vue-loader", options: { loaders: { sass: cssLoaders("vue-style-loader!css-loader!sass-loader", { extract: true }) } } }, ... { test: /.(scss|sass)$/, use: cssLoaders("style-loader!css-loader!sass-loader") }
再使用ExtractTextPlugin合并抽離到static/css/目錄
4. 定義全局常量cli命令行(webpack -p)使用process.env.NODE_ENV不如期望效果,使用不了,所以需要使用DefinePlugin插件定義,定義形式""development""或JSON.stringify(process.env.NODE_ENV),我使用這樣的寫法"development",結果報錯(針對webpack2),查找了一下網上資料,它是這樣講的,可以去看一下,設置如下:
new webpack.DefinePlugin({ "process.env": { NODE_ENV: options.dev ? JSON.stringify("development") : JSON.stringify("production") } })5. 使用eslint修正代碼規(guī)范
通過eslint來檢查代碼的規(guī)范性,通過定義一套配置項,來規(guī)范代碼,這樣多人協(xié)作,寫出來的代碼也會比較優(yōu)雅,不好的地方是,就是配置項太多,有些默認項設置我們不需要,但是確是處處限制我們,需要通過配置屏蔽掉,可以通過.eslintrc 文件或是package.json的eslintConfig,還有其他方式,可以到中文網看,這里我用的是package.json方式,如下:
... "eslintConfig": { "parser": "babel-eslint", "extends": "enough", "env": { "browser": true, "node": true, "commonjs": true, "es6": true }, "rules": { "linebreak-style": 0, "indent": [2, 4], "no-unused-vars": 0, "no-console": 0 }, "plugins": [ "html" ] }, ...
我們還需要安裝 npm install eslint eslint-config-enough eslint-loader --save-dev,eslint-config-enough是所謂的配置文件,這樣package.json的內容才能起效,但是不當當是這樣,對應編輯器也需要安裝對應的插件,sublime text 3需要安裝SublimeLinter、SublimeLinter-contrib-eslint插件。對于所有規(guī)則的詳解,可以去看官網,也可以去這里看,很詳細!
由于我們使用的是vue-loader,自然我們是希望能對.vue文件eslint,那么需要安裝eslint-plugin-html,在package.json中進行配置。然后對應webpack配置:
{ enforce: "pre", test: /.vue$/, loader: "eslint-loader", exclude: /node_modules/ }
我們會發(fā)現webpack v1和v2之間會有一些不同,比如webpack1對于預先加載器處理的執(zhí)行是這樣的,
module: { preLoaders: [ { test: /.js$/, loader: "eslint-loader" } ] }
更多的不同可以到中文網看,很詳細,不做拓展。
6. alias vue指向問題... alias: { vue: "vue/dist/vue" }, ...
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指向
之前的項目中使用的是用express啟動http服務,webpack-dev-middleware+webpack-hot-middleware,這里會用到compiler+compilation,這個是webpack的編譯器和編譯過程的一些知識,也不是很懂,后續(xù)要去做做功課,應該可以加深對webpack運行機制的理解。這樣做的話,感覺復雜很多,對于webpack2.0 devServer似乎功能更強大更加完善了,所以直接使用就可以了。如下:
devServer: { port: 8080, //端口號 proxy: { //方向代理 /api/auth/ => http://api.example.dev "/api/auth/": { target: "http://api.example.dev", changeOrigin: true, pathRewrite: { "^/api": "" } } }, publicPath: config.publicPath, stats: { colors: true } } //changeOrigin會修改HTTP請求頭中的Host為target的域名, 這里會被改為api.example.dev //pathRewrite用來改寫URL, 這里我們把/api前綴去掉,直接使用/auth/請求
webpack 2 打包實戰(zhàn)講解得非常好,非常棒。可以去看一下,一定會有所收獲!
8. 熱重載原理webpack中文網,講的還算清楚,不過可能太笨,看起來還是云里霧里的,似懂非懂的,補補課,好好看看。
9. localtunnel的使用Localtunnel 是一個可以讓內網服務器暴露到公網上的開源項目,使用可以看這里,
$ npm install -g localtunnel $ lt --port 8080 your url is: https://uhhzexcifv.localtunnel.me
這樣的話,可以把我們的本地網站暫時性地暴露到公網,可以對網站做一些線上線下對比,詳細內容可以去了解一下localtunnel,這里講的是通過上面配置,訪問https://uhhzexcifv.localtunnel.me,沒有達到理想效果,出現了Invalid Host header的錯誤,因為devServer缺少一個配置disableHostCheck: true,這樣的一個配置,很多文檔上面都沒有說明,字面上面的意思不要去檢查Host,這樣設置,便可以繞過這一層檢驗,設置的配置項在optionsSchema.json中,issue可以看這里
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87014.html
摘要:提前申明注意自己對腳手架的理解和認識,很多東西和理解都是形象上的手法,并不專業(yè)和官方一種項目構建工具,可以將和壓縮成一個文件。之后使用項目名進入項目根目錄,使用來自動安裝項目依賴。 提前申明 注意:自己對vue腳手架的理解和認識,很多東西和理解都是形象上的手法,并不專業(yè)和官方 webpack 一種項目構建工具,可以將css和js壓縮成一個文件。此外,可以提供測試用服務器。使用webpa...
摘要:那該怎么管理這兩個不同的項目呢解決子模塊用的的同學肯定一下子就想到子模塊的知識了。最后,也希望有想法的同學還有大佬多多留言,給點建議原文地址從零開始做前端架構腳手架參考資料官方文檔使用定制前端腳手架別人寫的腳手架文件操作相關文檔子模塊 前言 相信很多人都用過vue-cli或create-react-app或者類似的腳手架。腳手架方便我們復制,粘貼,或者clone代碼庫,而且還可以更具用...
摘要:可以譯作運行時過程全面分析和解析,這個全面分析涉及到比較基礎的或者復雜的重要前端概念和中的概念等。注本篇是運行時全解析系列文章的第一篇,首次發(fā)表于,友善轉載蟹蟹。附更多內容請參考核心維護者蔣豪群同學的的公開課視頻 Vue Runtime Full Analysis - VueCLI3 Get Start VRFA: (Vue Runtime Full Analysis) 可以譯作vue...
摘要:的外表,的心說在前面對于我個人來說,一個好的腳手架有助于我們心無旁騖地去學習一些庫例如和。所以說,為什么不弄個的呢我的想法就是將和盡量保持一致,除了它們的核心和。并不會對該文件夾下的文件進行處理。 react-webpack-boilerplate vue-cli的外表,React的心 說在前面 對于我個人來說,一個好的腳手架有助于我們心無旁騖地去學習一些庫例如Vue和React。vu...
摘要:然后類似一樣我的命名是可以在頁面的任何地方使用,如果你對具體的實現方法有興趣,歡迎點擊本文結尾的鏈接,去我的倉庫上查看。 前言 最近收到一個這樣的需求,要求做一個基于 vue 和 element-ui 的通用后臺框架頁,具體要求如下: 要求通用性高,需要在后期四十多個子項目中使用,所以大部分地方都做成可配置的. 要求做成腳手架的形式.可以 npm 安裝 要求實現多頁簽,并且可以通過瀏...
摘要:然后類似一樣我的命名是可以在頁面的任何地方使用,如果你對具體的實現方法有興趣,歡迎點擊本文結尾的鏈接,去我的倉庫上查看。 前言 最近收到一個這樣的需求,要求做一個基于 vue 和 element-ui 的通用后臺框架頁,具體要求如下: 要求通用性高,需要在后期四十多個子項目中使用,所以大部分地方都做成可配置的. 要求做成腳手架的形式.可以 npm 安裝 要求實現多頁簽,并且可以通過瀏...
閱讀 1923·2021-10-11 10:59
閱讀 1032·2021-09-07 09:59
閱讀 2226·2021-08-27 16:17
閱讀 2783·2019-08-30 15:54
閱讀 2274·2019-08-30 12:58
閱讀 1773·2019-08-30 12:53
閱讀 1465·2019-08-28 18:13
閱讀 733·2019-08-26 13:35