vue-cli腳手架-bulid下的配置文件
本文章適合初學(xué)者學(xué)習(xí),如有錯(cuò)請(qǐng)?zhí)岢觥=趯?duì)vue比較感興趣,所以準(zhǔn)備用vue寫一個(gè)blog。早期先對(duì)vue腳手架了解一下,對(duì)于新手官網(wǎng)建議先不用vue-cli,但我覺得如果沒有任何的依據(jù)憑自己寫一個(gè)項(xiàng)目(包括webpack的配置等)這無疑是浪費(fèi)時(shí)間的而且都最后還是是而非的。所以我覺得完全可以用腳手架建一個(gè)webpack項(xiàng)目,然后我們可以具體對(duì)應(yīng)它生成的文件學(xué)習(xí)(當(dāng)然這只是我的學(xué)習(xí)方法,我認(rèn)為這樣比較好學(xué),但不一定人人都是這樣的)。
在學(xué)習(xí)的過程中發(fā)現(xiàn)網(wǎng)上許多的簡(jiǎn)介都已經(jīng)過期(vue發(fā)展的過快了吧。。。。),所以我結(jié)合自己的項(xiàng)目和網(wǎng)上的資料備注一下,希望和其他的人一起討論。這個(gè)適合的版本為: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,不會(huì)的請(qǐng)百度然后先安裝nodejs。
2、安裝好nodejs之后,全局安裝vue-cli:npm install -g vue-cli。
3、新建webpack項(xiàng)目:vue init webpack projectname(這是比較完整的,我們學(xué)習(xí)用這個(gè)比較好)、vue init webpack-simple projectname(簡(jiǎn)易版的)。
注意:projectname項(xiàng)目名不能用中文。
4、“vue init webpack-simple projectname”創(chuàng)建新項(xiàng)目的目錄結(jié)構(gòu):
生成新項(xiàng)目時(shí)并沒有安裝依賴,需要進(jìn)入新的項(xiàng)目安裝依賴:cd projectname -> npm install。
新建項(xiàng)目時(shí),會(huì)需要填一些東西,但如果你都不想填也無所謂,全部默認(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)目會(huì)用到
(6)、Use ESLint to lint your code?:——eslint的格式驗(yàn)證非常嚴(yán)格,多一個(gè)空格少一個(gè)空格都會(huì)報(bào)錯(cuò)。個(gè)人覺得如果是平時(shí)練習(xí)的話可以選yes因?yàn)檫@個(gè)可以規(guī)范自己js代碼的書寫規(guī)范。但在實(shí)際開發(fā)項(xiàng)目中不建議使用,會(huì)影響開發(fā)效率。
(7)、Setup unit tests with Karma + Mocha 以及Setup e2e tests with Nightwatch這兩個(gè)是測(cè)試,可以不用安裝。

“vue init webpack projectname”創(chuàng)建新項(xiàng)目的目錄結(jié)構(gòu):


二、build目錄下配置文件之check-versions.js
這個(gè)文件并不是十分重要,只要稍微了解就行了。
/**
* 驗(yàn)證版本
*/
'use strict'
//chalk是一個(gè)顏色插件??梢酝ㄟ^
const chalk = require('chalk')
//semver一個(gè)版本控制插件
const semver = require('semver')
const packageConfig = require('../package.json')
//shelljss是nodejs對(duì)與多進(jìn)程的支持,是對(duì)于child_process封裝
const shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{//對(duì)應(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),
//要求版本,對(duì)應(yīng)package.json的engines所配置的信息
versionRequirement: packageConfig.engines.node
}
]
//npm環(huán)境中
if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
//執(zhí)行方法得到版本號(hào)
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]
//如果版本號(hào)不符合package.json文件中指定的版本號(hào),就執(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
這個(gè)文件主要用于處理有關(guān)于css方面的,主要對(duì)后面vue-loader.conf.js文件有關(guān)系,對(duì)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ū)別前者返回完整路徑,后者返回完整路徑的相對(duì)路徑
//例: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
//一般我們會(huì)壓縮js或者css以節(jié)省寬帶,但在開發(fā)壓縮就很難調(diào)試
//所以用sourceMap進(jìn)行關(guān)聯(lián),給出對(duì)應(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ǔ)配置放到一個(gè)數(shù)據(jù)中
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
//如果該函數(shù)傳遞了單獨(dú)的loder就加入到loaders數(shù)組中例如:sass或者less之類的
if (loader) {
loaders.push({
//加載對(duì)應(yīng)的loader
loader: loader + '-loader',
//es6方法Object.assign:主要用于合并對(duì)象的,淺拷貝
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:?jiǎn)为?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)
// 這個(gè)方法主要處理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
}
//用于返回腳手架錯(cuò)誤的函數(shù)
exports.createNotifierCallback = () => {
//使用node-notifier來發(fā)送桌面消息,包括應(yīng)用狀態(tài)改變以及錯(cuò)誤信息
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
從這個(gè)文件開始,webpack配置文件正式開始,前面的相當(dāng)于是這個(gè)文件參數(shù)般的存在。而實(shí)際上這個(gè)也不是正式會(huì)運(yùn)行的配置文件。一個(gè)項(xiàng)目有2中情況:開發(fā)環(huán)境和生成環(huán)境。這2中環(huán)境一些方面的配置是不一樣的,比如在生產(chǎn)環(huán)境我們會(huì)對(duì)js和css進(jìn)行壓縮以減少寬帶。這個(gè)文件實(shí)際上是這2中環(huán)境通用的配置。下面的webpack.dev.conf.js文件(開發(fā)環(huán)境)、
webpack.prod.conf.js(生產(chǎn)環(huán)境),這2個(gè)文件才是實(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')
//獲取對(duì)應(yīng)文件路徑的函數(shù)
//因?yàn)樵撐募窃陧?xiàng)目的二級(jí)文件build下,所以要加上../這樣才能找到像src這樣的目錄
function resolve (dir) {
//join方法用于將多個(gè)字符串結(jié)合成一個(gè)路徑字符串
//path在node中會(huì)經(jīng)常用到可以仔細(xì)了解一下path的各種方法
//__dirname:獲取當(dāng)前文件所在目錄的完整絕對(duì)路徑
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: {
//自動(dòng)解析確定的擴(kuò)展,在引入模塊時(shí)不帶擴(kuò)展名
//例如:import somejs from "@/some"
extensions: ['.js', '.vue', '.json'],
alias: {
// 后面的$符號(hào)指精確匹配
// 也就是說只能使用 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都會(huì)用到這個(gè)文件的配置
* 具體可以參考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的錯(cuò)誤和日志搜集起來展現(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文件性價(jià)比最高
// 生產(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插件,專門用來定義全局變量的
// 下面定義一個(gè)全局變量 process.env 并且值是如下
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
// 這個(gè)插件幫助你實(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
這個(gè)文件配置了一些全局屬性,分別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)用到時(shí)候具體了解,本文章就不講了。
本文章只是簡(jiǎn)單地理解一下webpack的配置文件,其中用到的各種插件和插件使用方面都沒有涉及。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue 兩個(gè)字段聯(lián)合校驗(yàn)之修改密碼功能的實(shí)現(xiàn)
本文以校驗(yàn)兩次密碼的一致性應(yīng)用,給出兩個(gè)可變屬性值的字段之間的聯(lián)合校驗(yàn)的典型解決方案,通過實(shí)例代碼給大家介紹Vue 兩個(gè)字段聯(lián)合校驗(yàn)之修改密碼功能的實(shí)現(xiàn),需要的朋友一起看看吧2021-07-07
vue 百度地圖(vue-baidu-map)繪制方向箭頭折線實(shí)例代碼詳解
這篇文章主要介紹了vue 百度地圖(vue-baidu-map)繪制方向箭頭折線,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Vue生命周期和鉤子函數(shù)的詳解與經(jīng)典面試題
Vue生命周期是指vue實(shí)例對(duì)象從創(chuàng)建之初到銷毀的過程,vue所有功能的實(shí)現(xiàn)都是圍繞其生命周期進(jìn)行的,下面這篇文章主要給大家介紹了關(guān)于Vue生命周期和鉤子函數(shù)的相關(guān)資料,需要的朋友可以參考下2021-10-10
Vue項(xiàng)目利用axios請(qǐng)求接口下載excel
這篇文章主要為大家詳細(xì)介紹了Vue項(xiàng)目利用axios請(qǐng)求接口下載excel,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11
vue中用H5實(shí)現(xiàn)文件上傳的方法實(shí)例代碼
本篇文章主要介紹了vue中用H5實(shí)現(xiàn)文件上傳的方法實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05

