vue-cli腳手架-bulid下的配置文件
本文章適合初學(xué)者學(xué)習(xí),如有錯請?zhí)岢觥=趯ue比較感興趣,所以準(zhǔn)備用vue寫一個blog。早期先對vue腳手架了解一下,對于新手官網(wǎng)建議先不用vue-cli,但我覺得如果沒有任何的依據(jù)憑自己寫一個項(xiàng)目(包括webpack的配置等)這無疑是浪費(fèi)時間的而且都最后還是是而非的。所以我覺得完全可以用腳手架建一個webpack項(xiàng)目,然后我們可以具體對應(yīng)它生成的文件學(xué)習(xí)(當(dāng)然這只是我的學(xué)習(xí)方法,我認(rèn)為這樣比較好學(xué),但不一定人人都是這樣的)。
在學(xué)習(xí)的過程中發(fā)現(xiàn)網(wǎng)上許多的簡介都已經(jīng)過期(vue發(fā)展的過快了吧。。。。),所以我結(jié)合自己的項(xiàng)目和網(wǎng)上的資料備注一下,希望和其他的人一起討論。這個適合的版本為:nodejs(6.10.2)、vue(2.5.2)、vue-router(3.0.1)和webpack(3.6.0)的。適合的環(huán)境為windows的,其他的系統(tǒng)我也不知道可不可以用。
一、vue-cli安裝、webpack項(xiàng)目新建
1、默認(rèn)電腦已經(jīng)安裝了node,不會的請百度然后先安裝nodejs。
2、安裝好nodejs之后,全局安裝vue-cli:npm install -g vue-cli。
3、新建webpack項(xiàng)目:vue init webpack projectname(這是比較完整的,我們學(xué)習(xí)用這個比較好)、vue init webpack-simple projectname(簡易版的)。
注意:projectname項(xiàng)目名不能用中文。
4、“vue init webpack-simple projectname”創(chuàng)建新項(xiàng)目的目錄結(jié)構(gòu):
生成新項(xiàng)目時并沒有安裝依賴,需要進(jìn)入新的項(xiàng)目安裝依賴:cd projectname -> npm install。
新建項(xiàng)目時,會需要填一些東西,但如果你都不想填也無所謂,全部默認(rèn)、全部yes都行:
(1)、Project name:——項(xiàng)目名稱
(2)、Project description:——項(xiàng)目描述
(3)、Author:——作者
(4)、Vue build:——構(gòu)建模式,一般默認(rèn)選擇第一種
(5)、Install vue-router?:——是否安裝引入vue-router,這里選是,vue-router是路由組件,后面構(gòu)建項(xiàng)目會用到
(6)、Use ESLint to lint your code?:——eslint的格式驗(yàn)證非常嚴(yán)格,多一個空格少一個空格都會報錯。個人覺得如果是平時練習(xí)的話可以選yes因?yàn)檫@個可以規(guī)范自己js代碼的書寫規(guī)范。但在實(shí)際開發(fā)項(xiàng)目中不建議使用,會影響開發(fā)效率。
(7)、Setup unit tests with Karma + Mocha 以及Setup e2e tests with Nightwatch這兩個是測試,可以不用安裝。
“vue init webpack projectname”創(chuàng)建新項(xiàng)目的目錄結(jié)構(gòu):
二、build目錄下配置文件之check-versions.js
這個文件并不是十分重要,只要稍微了解就行了。
/** * 驗(yàn)證版本 */ 'use strict' //chalk是一個顏色插件。可以通過 const chalk = require('chalk') //semver一個版本控制插件 const semver = require('semver') const packageConfig = require('../package.json') //shelljss是nodejs對與多進(jìn)程的支持,是對于child_process封裝 const shell = require('shelljs') function exec (cmd) { return require('child_process').execSync(cmd).toString().trim() } const versionRequirements = [ {//對應(yīng)node的版本 name: 'node', //當(dāng)前環(huán)境版本,semver.clean把當(dāng)前環(huán)境版本信息轉(zhuǎn)化規(guī)定格式,也是' =v1.2.3 '->'1.2.3' currentVersion: semver.clean(process.version), //要求版本,對應(yīng)package.json的engines所配置的信息 versionRequirement: packageConfig.engines.node } ] //npm環(huán)境中 if (shell.which('npm')) { versionRequirements.push({ name: 'npm', //執(zhí)行方法得到版本號 currentVersion: exec('npm --version'), versionRequirement: packageConfig.engines.npm }) } module.exports = function () { const warnings = [] for (let i = 0; i < versionRequirements.length; i++) { const mod = versionRequirements[i] //如果版本號不符合package.json文件中指定的版本號,就執(zhí)行下面的代碼 if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { warnings.push(mod.name + ': ' + chalk.red(mod.currentVersion) + ' should be ' + chalk.green(mod.versionRequirement) ) } } if (warnings.length) { console.log('') console.log(chalk.yellow('To use this template, you must update following to modules:')) console.log() for (let i = 0; i < warnings.length; i++) { const warning = warnings[i] console.log(' ' + warning) } console.log() process.exit(1) } }
三、build目錄下配置文件之utils.js
這個文件主要用于處理有關(guān)于css方面的,主要對后面vue-loader.conf.js文件有關(guān)系,對webpack配置loaders方面也有影響。
/** * webpack開發(fā)環(huán)境:主要用來處理css-loader和vue-style-loader */ 'use strict' const path = require('path') const config = require('../config') //引入extract-text-webpack-plugin插件,用來將css提取到單獨(dú)的css文件中 const ExtractTextPlugin = require('extract-text-webpack-plugin') const packageConfig = require('../package.json') exports.assetsPath = function (_path) { //process.env.NODE_ENV在bulid.js中定義 //如果為生產(chǎn)環(huán)境assetsSubDirectory為“static”,否則也為“static” //config.build.assetsSubDirectory與config.dev.assetsSubDirectory都在config/index中定義 const assetsSubDirectory = process.env.NODE_ENV === 'production' ? config.build.assetsSubDirectory : config.dev.assetsSubDirectory //path.join和path.posix.join區(qū)別前者返回完整路徑,后者返回完整路徑的相對路徑 //例:path.join是E:/shishans/blogsss/static,path.posix.join是static return path.posix.join(assetsSubDirectory, _path) } exports.cssLoaders = function (options) { options = options || {} //css-loader的基本配置 const cssLoader = { loader: 'css-loader', options: { //option用于配置loder的 //是否開啟cssMap,默認(rèn)是false //一般我們會壓縮js或者css以節(jié)省寬帶,但在開發(fā)壓縮就很難調(diào)試 //所以用sourceMap進(jìn)行關(guān)聯(lián),給出對應(yīng)的sourceMap文件 sourceMap: options.sourceMap } } const postcssLoader = { loader: 'postcss-loader', options: { sourceMap: options.sourceMap } } // generate loader string to be used with extract text plugin function generateLoaders (loader, loaderOptions) { //將上面的基礎(chǔ)配置放到一個數(shù)據(jù)中 const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] //如果該函數(shù)傳遞了單獨(dú)的loder就加入到loaders數(shù)組中例如:sass或者less之類的 if (loader) { loaders.push({ //加載對應(yīng)的loader loader: loader + '-loader', //es6方法Object.assign:主要用于合并對象的,淺拷貝 options: Object.assign({}, loaderOptions, { sourceMap: options.sourceMap }) }) } // Extract CSS when that option is specified // (which is the case during production build) // extract自定義屬性,用ExtractTextPlugin.extract控制是否把文件單獨(dú)提取 // true:單獨(dú)提取,false表示不提取 if (options.extract) { return ExtractTextPlugin.extract({ use: loaders, fallback: 'vue-style-loader' }) } else { //[].concat()方法用于連接數(shù)組 return ['vue-style-loader'].concat(loaders) } } // https://vue-loader.vuejs.org/en/configurations/extract-css.html return { css: generateLoaders(),//返回[cssLoader, vue-style-loader] postcss: generateLoaders(),//返回[cssLoader, vue-style-loader] less: generateLoaders('less'),//返回[cssLoader, vue-style-loader, less] sass: generateLoaders('sass', { indentedSyntax: true }), scss: generateLoaders('sass'), stylus: generateLoaders('stylus'), styl: generateLoaders('stylus') } } // Generate loaders for standalone style files (outside of .vue) // 這個方法主要處理import這種方式導(dǎo)入的文件類型的打包 exports.styleLoaders = function (options) { const output = [] const loaders = exports.cssLoaders(options) for (const extension in loaders) { const loader = loaders[extension] output.push({ test: new RegExp('\\.' + extension + '$'), use: loader }) } return output } //用于返回腳手架錯誤的函數(shù) exports.createNotifierCallback = () => { //使用node-notifier來發(fā)送桌面消息,包括應(yīng)用狀態(tài)改變以及錯誤信息 const notifier = require('node-notifier') return (severity, errors) => { if (severity !== 'error') return const error = errors[0] const filename = error.file && error.file.split('!').pop() notifier.notify({ title: packageConfig.name, message: severity + ': ' + error.name, subtitle: filename || '', icon: path.join(__dirname, 'logo.png') }) } }
四、build目錄下配置文件之webpack.base.conf.js
從這個文件開始,webpack配置文件正式開始,前面的相當(dāng)于是這個文件參數(shù)般的存在。而實(shí)際上這個也不是正式會運(yùn)行的配置文件。一個項(xiàng)目有2中情況:開發(fā)環(huán)境和生成環(huán)境。這2中環(huán)境一些方面的配置是不一樣的,比如在生產(chǎn)環(huán)境我們會對js和css進(jìn)行壓縮以減少寬帶。這個文件實(shí)際上是這2中環(huán)境通用的配置。下面的webpack.dev.conf.js文件(開發(fā)環(huán)境)、
webpack.prod.conf.js(生產(chǎn)環(huán)境),這2個文件才是實(shí)際環(huán)境運(yùn)行使用的配置文件。
/** * webpack開發(fā)環(huán)境和生成環(huán)境通用的配置 */ 'use strict' const path = require('path') const utils = require('./utils') const config = require('../config') const vueLoaderConfig = require('./vue-loader.conf') //獲取對應(yīng)文件路徑的函數(shù) //因?yàn)樵撐募窃陧?xiàng)目的二級文件build下,所以要加上../這樣才能找到像src這樣的目錄 function resolve (dir) { //join方法用于將多個字符串結(jié)合成一個路徑字符串 //path在node中會經(jīng)常用到可以仔細(xì)了解一下path的各種方法 //__dirname:獲取當(dāng)前文件所在目錄的完整絕對路徑 return path.join(__dirname, '..', dir) } //eslint用來檢查我們寫的js代碼是否滿足指定的規(guī)則 const createLintingRule = () => ({ test: /\.(js|vue)$/, loader: 'eslint-loader', enforce: 'pre', include: [resolve('src'), resolve('test')], options: { formatter: require('eslint-friendly-formatter'), emitWarning: !config.dev.showEslintErrorsInOverlay } }) module.exports = { context: path.resolve(__dirname, '../'), entry: { //入口文件是src下的main.js app: './src/main.js' }, output: { path: config.build.assetsRoot, filename: '[name].js', publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath }, resolve: { //自動解析確定的擴(kuò)展,在引入模塊時不帶擴(kuò)展名 //例如:import somejs from "@/some" extensions: ['.js', '.vue', '.json'], alias: { // 后面的$符號指精確匹配 // 也就是說只能使用 import vuejs from "vue" 這樣的方式導(dǎo)入vue.esm.js文件 'vue$': 'vue/dist/vue.esm.js', // resolve('src') 其實(shí)在這里就是項(xiàng)目根目錄中的src目錄 // 例如引用src目錄下的some.js方法:import somejs from "@/some.js" // 用@來代替../src '@': resolve('src'), } }, module: { rules: [ ...(config.dev.useEslint ? [createLintingRule()] : []), { test: /\.vue$/, loader: 'vue-loader', options: vueLoaderConfig }, { test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('media/[name].[hash:7].[ext]') } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } } ] }, node: { // prevent webpack from injecting useless setImmediate polyfill because Vue // source contains it (although only uses it if it's native). setImmediate: false, // prevent webpack from injecting mocks to Node native modules // that does not make sense for the client dgram: 'empty', fs: 'empty', net: 'empty', tls: 'empty', child_process: 'empty' } }
五、build目錄下配置文件之webpack.dev.conf.js
webpack.prod.conf.js也差不多。這2者之間的差別以后再討論。
/** * 此文件用于開發(fā)環(huán)境下的webpack配置 * 就本項(xiàng)目執(zhí)行npm run dev 和 npm run start都會用到這個文件的配置 * 具體可以參考JavaScript中"scripts"的配置 */ 'use strict' const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge') const path = require('path') const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') //生成html文件 const HtmlWebpackPlugin = require('html-webpack-plugin') //friendly-errors-webpack-plugin:把webpack的錯誤和日志搜集起來展現(xiàn)給用戶 const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') const portfinder = require('portfinder') const HOST = process.env.HOST const PORT = process.env.PORT && Number(process.env.PORT) const devWebpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) }, // cheap-module-eval-source-map is faster for development // devtool是開發(fā)工具選項(xiàng),用來指定如何生成sourcemap文件,cheap-module-eval-source-map此款soucemap文件性價比最高 // 生產(chǎn)環(huán)境:#source-map // 開發(fā)環(huán)境:#cheap-module-eval-source-map 編譯消耗小 devtool: config.dev.devtool, // these devServer options should be customized in /config/index.js devServer: { clientLogLevel: 'warning', historyApiFallback: { rewrites: [ { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, ], }, hot: true, contentBase: false, // since we use CopyWebpackPlugin. compress: true, host: HOST || config.dev.host, port: PORT || config.dev.port, open: config.dev.autoOpenBrowser, overlay: config.dev.errorOverlay ? { warnings: false, errors: true } : false, publicPath: config.dev.assetsPublicPath, proxy: config.dev.proxyTable, quiet: true, // necessary for FriendlyErrorsPlugin watchOptions: { poll: config.dev.poll, } }, plugins: [ // DefinePlugin內(nèi)置webpack插件,專門用來定義全局變量的 // 下面定義一個全局變量 process.env 并且值是如下 new webpack.DefinePlugin({ 'process.env': require('../config/dev.env') }), // 這個插件幫助你實(shí)現(xiàn)無刷新加載,關(guān)于內(nèi)部實(shí)現(xiàn)原理 new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. new webpack.NoEmitOnErrorsPlugin(), // https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true }), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.dev.assetsSubDirectory, ignore: ['.*'] } ]) ] }) module.exports = new Promise((resolve, reject) => { portfinder.basePort = process.env.PORT || config.dev.port portfinder.getPort((err, port) => { if (err) { reject(err) } else { // publish the new Port, necessary for e2e tests process.env.PORT = port // add port to devServer config devWebpackConfig.devServer.port = port // Add FriendlyErrorsPlugin devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ compilationSuccessInfo: { messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], }, onErrors: config.dev.notifyOnErrors ? utils.createNotifierCallback() : undefined })) resolve(devWebpackConfig) } }) })
六、config目錄下之index.js
這個文件配置了一些全局屬性,分別dev和build用于區(qū)別開發(fā)環(huán)境和生產(chǎn)環(huán)境不同的地方。
七、總結(jié)
在vue2.5.2中取消了build目錄中的dev-server.js和dev-client.js文件,改用webpack.dev.conf.js代替,所以 配置本地訪問在webpack.dev.conf.js里配置即可。具體如何配置以后運(yùn)用到時候具體了解,本文章就不講了。
本文章只是簡單地理解一下webpack的配置文件,其中用到的各種插件和插件使用方面都沒有涉及。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue element-ul實(shí)現(xiàn)展開和收起功能的實(shí)例代碼
這篇文章主要介紹了vue element-ul實(shí)現(xiàn)展開和收起功能的實(shí)例代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11Vue3+El-Plus實(shí)現(xiàn)表格行拖拽功能完整代碼
在vue3+elementPlus網(wǎng)站開發(fā)中,詳細(xì)完成el-table表格的鼠標(biāo)拖拽/拖曳/拖動排序,下面這篇文章主要給大家介紹了關(guān)于Vue3+El-Plus實(shí)現(xiàn)表格行拖拽功能的相關(guān)資料,需要的朋友可以參考下2024-05-05使用Vue開發(fā)一個實(shí)時性時間轉(zhuǎn)換指令
我們就來實(shí)現(xiàn)這樣一個Vue自定義指令v-time,將表達(dá)式傳入的時間戳實(shí)時轉(zhuǎn)換為相對時間。下面小編給大家?guī)砹耸褂肰ue開發(fā)一個實(shí)時性時間轉(zhuǎn)換指令,需要的朋友參考下吧2018-01-01vue-seamless-scroll 實(shí)現(xiàn)簡單自動無縫滾動且添加對應(yīng)點(diǎn)擊事件的簡單整理
vue-seamless-scroll是一個基于Vue.js的簡單無縫滾動組件, 基于requestAnimationFrame實(shí)現(xiàn),配置多滿足多樣需求,目前支持上下左右無縫滾動,單步滾動,及支持水平方向的手動切換功能,本節(jié)介紹,vue添加 vue-seamless-scroll實(shí)現(xiàn)自動無縫滾動的效果,并對應(yīng)添加點(diǎn)擊事件2023-01-01Vite配置優(yōu)雅的code?spliiting代碼分割詳解
這篇文章主要為大家介紹了Vite配置優(yōu)雅的code?spliiting代碼分割詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08vue中v-for數(shù)據(jù)狀態(tài)值變了,但是視圖沒改變的解決方案
這篇文章主要介紹了vue中v-for數(shù)據(jù)狀態(tài)值變了,但是視圖沒改變的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06在vue+element-plus中無法同時使用v-for和v-if的問題及解決方法
由于路由中存在不需要遍歷的數(shù)據(jù)所以像用v-if來過濾,但是報錯,百度說vue不能同時使用v-if和v-for,今天小編給大家分享解決方式,感興趣的朋友跟隨小編一起看看吧2023-07-07