最近在公司內部推 Vuejs
,vue-cli
webpack 生成的項目沒法知足現有的需求,因而乎開始改造 vue-cli
初始化的項目, 主要解決項目多頁面和外部引入樣式文件沒有 autoprefixer 的問題。javascript
vue webpack 模板默認是 SPA 項目,改爲多頁面則須要把單入口變爲多入口,生成多個html文件。css
|—— src
|—— assets
|—— components // 多個頁面間的公共組件
|—— pages
|—— hello
|—— hello.vue // 頁面主vue文件,和文件夾一致方便搜索
|—— index.html // html模板文件
|—— main.js // 入口文件複製代碼
pages 文件夾下每一個頁面都新建一個文件夾,固定三個文件 index.html
、 main.js
、 page.vue
, 後續會有代碼來識別產生多入口html
構建邏輯部分須要自定識別 pages 下的文件夾,生成多個 entry
。vue
首先,增長一個 page.js
初始化全部的頁面信息java
// page.js
var glob = require('glob');
var path = require('path');
var fs = require('fs');
var chalk = require('chalk');
var ENTRY = 'main.js';
var PAGE_FLODER = path.resolve(__dirname, '../src/pages/');
var PAGES = PAGE_FLODER + '/**/' + ENTRY;
var TEMPLATE = 'index.html';
function initPages() {
var pages = {};
glob.sync(PAGES).forEach(function (entry) {
var pageName = getPageName(entry);
var templatePath = getTemplatePath(entry);
if (!fs.existsSync(templatePath)) {
console.log(chalk.yellow(pageName + '找不到模板文件'));
return;
}
pages[pageName] = {
name: pageName,
entry: entry,
template: templatePath
};
});
return pages;
}
function getPageName(filePath) {
return filePath.substring(PAGE_FLODER.length + 1, filePath.indexOf(ENTRY) - 1);
}
function getTemplatePath(filePath) {
var templatePath = filePath.substring(0, filePath.indexOf(ENTRY));
templatePath += TEMPLATE;
return templatePath;
}
module.exports = initPages();複製代碼
而後 修改 config/index.js
android
module.exports = {
pages: require('./page'), // 增長page的配置
// ...
};複製代碼
接下,utils.js
增長兩個函數用來生成多個 entry
和 HtmlWebpackPlugin
webpack
// utils.js
//...
exports.getEntry = function () {
var entry = {};
Object.keys(config.pages).forEach(function (name) {
entry[name] = config.pages[name].entry;
});
return entry;
}
exports.getHtmlPlugin = function () {
var assetsSubDirectory = process.env.NODE_ENV === 'production' ?
config.build.assetsSubDirectory :
config.dev.assetsSubDirectory;
return Object.keys(config.pages).map(function (name) {
return new HtmlWebpackPlugin ({
template: config.pages[name].template,
filename: name + '.html',
inject: true,
chunks: ['vendor', 'manifest', name],
minify: env === 'production' ? {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
} : undefined,
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: env === 'production' ? 'dependency' : undefined
})
})
}複製代碼
最後改動 webpack.base.conf.js
、 webpack.dev.conf.js
和 webpack.prod.conf.js
ios
// webpack.base.conf.js
// ...
module.exports = {
entry: utils.getEntry() // 多入口配置
// ...
}複製代碼
// webpack.dev.conf.js
// ...
module.exports = merge(baseWebpackConfig, {
// ...
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
].concat(utils.getHtmlPlugin()), // 加入生成的多頁面 HtmlWebpackPlugin
});複製代碼
// webpack.prod.conf.js
//...
webpackConfig.plugins = webpackConfig.plugins.concat(utils.getHtmlPlugin()); // 加上這行代碼
//...複製代碼
ok,大功告成, 這樣一來就變爲多頁面項目了(這樣一來每一個頁面至少須要三個文件,本身寫了一個atom插件,新建頁面時自動生成相關文件和基礎代碼)。git
.vue
文件寫的樣式都會通過 postcss
處理,可是項目中重構和js須要分開工做,因此須要將css文件獨立出去,再在入口文件中引入,這是發現沒有樣式沒有進過 postcss
處理.github
這裏須要在樣式加載時使用 postcss-loader
處理
npm install postcss-loader --save-dev複製代碼
// utils.js
exports.cssLoaders = function (options) {
// ...
return {
css: generateLoaders(['css', 'postcss']),
postcss: generateLoaders(['css', 'postcss']),
less: generateLoaders(['css', 'postcss', 'less']),
sass: generateLoaders(['css', 'postcss', 'sass?indentedSyntax']),
scss: generateLoaders(['css', 'postcss', 'sass']),
stylus: generateLoaders(['css', 'postcss', 'stylus']),
styl: generateLoaders(['css', 'postcss', 'stylus'])
};
}複製代碼
// webpack.base.conf.js
var postcssConfig = [
require('autoprefixer')({
browsers: ['last 5 versions', 'android >= 4.2', 'ios >= 7']
})
];
module.exports = {
// ...
postcss: postcssConfig, // 增長postcss配置
vue: {
loaders: utils.cssLoaders({
sourceMap: useCssSourceMap
}),
postcss: postcssConfig
}
}複製代碼
最近又發現 vue webpack
模板又升級到了 webpack 2.2
立刻準備入一波坑了。