專案建立
# git clone project
git clone https://github.com/freeshineit/vue2_config.git
# install dependencies
cd vue2_config && npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
複製程式碼
vue專案配置簡介
config 資料夾下的配置檔案
config/dev.env.js
module.exports = merge(prodEnv, {
NODE_ENV: `"development"` // node環境為開發環境
})
複製程式碼
config/prod.env.js
module.exports = {
NODE_ENV: `"production"` // node環境為生產環境
}
複製程式碼
config/index.js
development
dev: { //開發環境配置項
assetsSubDirectory: `static`, // 虛擬靜態資源地址
assetsPublicPath: `/`,
proxyTable: {}, // 伺服器代理
// Various Dev Server settings
host: `localhost`, // can be overwritten by process.env.HOST
port: 8080, // 本地伺服器開啟的埠。如果被佔用,則會自動開啟一個端
autoOpenBrowser: false, // 服務開啟是否自動開啟瀏覽器
errorOverlay: true, // 是否錯誤疊加
notifyOnErrors: true, // 是否通知錯誤
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
useEslint: true, // 是否開啟eslint程式碼檢查
// if 值為true,eslint顯示錯誤和警告的錯誤也將被覆蓋
// 在瀏覽器中.
showEslintErrorsInOverlay: false,
//...
}
複製程式碼
production
build: { // 生產環境配置項
index: path.resolve(__dirname, `../dist/index.html`), // 打包生成模版
assetsRoot: path.resolve(__dirname, `../dist`), // 打包根路徑
assetsSubDirectory: `static`, // 打包靜態資源地址
assetsPublicPath: `/`, // 公共路徑
// 能夠提供將壓縮檔案恢復到原始檔原始位置的對映程式碼的方式,這意味著你可以在優化壓縮程式碼後輕鬆的進行除錯
productionSourceMap: true, // sourcemap
// ...
}
複製程式碼
build 檔案下的配置檔案
build/build.js
// 移除已經編譯的檔案
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
// 當移除檔案成功,執行回撥時重新打包專案
webpack(webpackConfig, (err, stats) => {
spinner.stop() // 停止ora 的loading
if (err) throw err // 出錯 丟擲錯誤
// 在編譯完成的回撥函式中,在終端輸出編譯的檔案
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + `
`)
if (stats.hasErrors()) { // build 失敗
console.log(chalk.red(` Build failed with errors.
`))
process.exit(1) // 程式退出
}
console.log(chalk.cyan(` Build complete.
`)) // build 完成
console.log(chalk.yellow(
` Tip: built files are meant to be served over an HTTP server.
` +
` Opening index.html over file:// won`t work.
`
)) // 在終端中輸出提醒文案
})
})
複製程式碼
build/utils.js
//根據`_path`生成資源路徑和檔案
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === `production`
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
//...
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
// 要使用動態樣式語言,你可下載下面幾種less、sass、stylus
// 例如安裝less執行: npm i -S less less-loader
// 就可以使用less了
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders(`less`),
sass: generateLoaders(`sass`, { indentedSyntax: true }),
scss: generateLoaders(`sass`),
stylus: generateLoaders(`stylus`),
styl: generateLoaders(`stylus`)
}
//...
複製程式碼
build/vue-loader.conf.js
// 是vue-loader的一些配置項
module.exports = {
// 呼叫utils工具類生成樣式loader的配置
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
}),
// ...
}
複製程式碼
build/webpack.base.conf.js
module.exports = {
context: path.resolve(__dirname, `../`),
entry: { // 入口檔案
app: `./src/main.js`
},
output: { // 編譯輸出檔案
path: config.build.assetsRoot, //匯出目錄的絕對路徑
filename: `[name].js`, //匯出檔案的檔名
publicPath: process.env.NODE_ENV === `production`
? config.build.assetsPublicPath
: config.dev.assetsPublicPath //生產模式或開發模式下html、js等檔案內部引用的公共路徑
},
resolve: {
extensions: [`.js`, `.vue`, `.json`], //自動解析確定的擴充名,使匯入模組時可以不帶擴充名
alias: { // 建立import或require的別名 方便簡寫匯入路徑
`vue$`: `vue/dist/vue.esm.js`,
`@`: resolve(`src`),
}
}
//...
}
複製程式碼
build/webpack.dev.conf.js
const devWebpackConfig = merge(baseWebpackConfig, {
// ...
plugins: [ // 外掛配置
new webpack.DefinePlugin({ // webpack 自帶的外掛
`process.env`: require(`../config/dev.env`)
}),
new webpack.HotModuleReplacementPlugin(), // webpack 自帶的外掛
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. // webpack 自帶的外掛
new webpack.NoEmitOnErrorsPlugin(), // webpack 自帶的外掛
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({ // html模版處理配置
filename: `index.html`, // 生成檔案
template: `index.html`, // 模版檔案
inject: true //注入的js檔案將會被放在body標籤中,當值為`head`時,將被放在head標籤中
}),
// copy custom static assets
new CopyWebpackPlugin([ // 複製外掛 , 只要時複製static資料夾中檔案到config.dev.assetsSubDirectory資料夾下
{
from: path.resolve(__dirname, `../static`),
to: config.dev.assetsSubDirectory,
ignore: [`.*`] //忽視.*檔案
}
])
],
// ...
})
複製程式碼
build/webpack.prod.conf.js
const webpackConfig = merge(baseWebpackConfig, {
// ...
output: { // 生成環境 編譯輸出檔案
path: config.build.assetsRoot, // 匯出檔案目錄
filename: utils.assetsPath(`js/[name].[chunkhash].js`), //匯出js檔名,檔名帶有chunkhash碼
chunkFilename: utils.assetsPath(`js/[id].[chunkhash].js`) // 非入口檔案的檔名,而又需要被打包出來的檔案命名配置,如按需載入的模組
},
plugins: [ // webpack 外掛配置
new webpack.DefinePlugin({
`process.env`: env //配置全域性環境為生產環境
}),
new UglifyJsPlugin({ // js程式碼壓縮外掛
uglifyOptions: {
compress: { // 程式碼壓縮配置
warnings: false // 是否顯示警告, false 不顯示
}
},
sourceMap: config.build.productionSourceMap, // 是否生產sourcemap檔案
parallel: true // 並行
}),
new ExtractTextPlugin({ // 抽取css 樣式表 單獨打包
filename: utils.assetsPath(`css/[name].[contenthash].css`), // 匯出css檔名,檔名帶有contenthash碼
//設定下面選項為`false`不會從程式碼分割塊中提取CSS。
//他們的CSS將被插入style-loader時,程式碼分割塊通過webpack已載入
//它的當前設定為`true`, 因為我們看到sourcemaps都包括在程式碼分割bundle, 以及當它的`假`增加檔案大小
// https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true, // 所有塊
}),
// 壓縮提取的CSS。我們正在使用這個外掛,使之成為可能
// 重複的CSS從不同的元件可以被刪除(deduped)
new OptimizeCSSPlugin({ // 壓縮抽取到css
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// 生成在 `dist` 檔案下 `index.html`
// 你可以通過編輯/ index.html自定義輸出(自定義模版中到內容)
new HtmlWebpackPlugin({
filename: config.build.index, // 生成到檔名
template: `index.html`, // 模版(當模版不存在時,生產檔案時雖然生成了,但是有點問題)
inject: true, //注入的js檔案將會被放在body標籤中,當值為`head`時,將被放在head標籤中
minify: { // html壓縮配置
removeComments: true, //移除html中的註釋
collapseWhitespace: true, // 移除html中的空格
removeAttributeQuotes: true //移除html元素中屬性的引號
},
chunksSortMode: `dependency` // 按照依賴的順序引入
}),
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.ModuleConcatenationPlugin(),
// 分離公共js到vendor檔案中去
new webpack.optimize.CommonsChunkPlugin({
name: `vendor`, // 檔名
minChunks (module) { //宣告公共的模組來自node_modules資料夾
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, `../node_modules`)
) === 0
)
}
}),
// 執行時模組提取webpack表現為了自己的檔案以防止每當應用程式包更新vendor檔案雜湊被更新
// 下面主要是將執行時程式碼提取到單獨的manifest檔案中,防止其影響vendor.js
new webpack.optimize.CommonsChunkPlugin({
name: `manifest`,
minChunks: Infinity
}),
// 本例項程式碼分塊,將它們捆在一個單獨的塊中提取共享塊,類似於vendor檔案的塊
new webpack.optimize.CommonsChunkPlugin({
name: `app`,
async: `vendor-async`,
children: true,
minChunks: 3
}),
// 複製指定檔案靜態資源, 下面將static檔案內的複製靜態資源內容複製到指定資料夾
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, `../static`),
to: config.build.assetsSubDirectory,
ignore: [`.*`]
}
])
]
})
複製程式碼
小結
使用vue-cli 腳手架建立,其實很簡單的,主要是和後臺合作,專案整合在一起。開發者瞭解webpack的相關配置非常有利於專案構建。如果搞不懂的話,自己可以去嘗試修改配置檢視效果。