前情提纲
上一篇文章引见了现在前端比较盛行的种种编辑器,以及种种盛行的打包体式格局,末了给了一个Gulp的例子,这个例子照样14年的时刻写的,另有一些能够优化的空间,就不议论了,这篇文章主要讲现在炽热的打包构建体式格局–Webpack的运用体式格局。
主菜–没有开胃汤
实在Webpack的入门指点文章异常多,设置体式格局也各有百般,这里我引荐题恭弘=叶 恭弘大神的入门级指南–Webpack 入门指迷,假如不知道Webpack是什么或许不是很清晰各项设置寄义的开辟者,能够看此文章扫扫盲。毕竟我这篇文章并非迥殊基础。
一、base.js
var path = require('path')
var baseConfig = {
resolve: {
extensions: ['', '.js'],
fallback: [path.join(__dirname, '../node_modules')],
alias: {
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '../src/assets'),
'components': path.resolve(__dirname, '../src/components')
}
},
module: {
loaders: [{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
}, {
test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url?limit=8192&context=client&name=[path][name].[hash:7].[ext]'
},
{
test: /\.css$/,
loader: 'style!css!autoprefixer',
},
{
test: /\.scss$/,
loader: 'style!css!autoprefixer!sass'
}]
}
};
module.exports = baseConfig;
解读下这个基础设置:
1、resolve 剖析模块依靠的时刻,受影响的设置项。
extensions 决议了哪些文件后缀在援用的时刻能够省略点,Webpack协助你补全称号。
fallback 当webpack在 root(默许当前文件夹,设置时要绝对途径) 和 modulesDirectories(默许当前文件夹,相对途径)设置下面找不到相干modules,去哪一个文件夹下找modules
alias 这个人人应当比较熟习,requirejs之类的都有,就是别号,协助你疾速指向文件途径,少写不少代码,而且不必体贴层级关联,须要注重的是:在scss之类的css预编译中援用要加上~,以便于让loader识别是别号援用途径。
2、module 剖析差异文件运用哪些loader,这个比较简单,许多文章都有,就不多说了,注重的是,这里的scss能够换成你本身的预编译器,比方:sass、less、stylus等,或许直接用postcss都行,固然还能够用一种通用要领,背面补上。
二、开辟环境设置–config
var webpack = require('webpack');
var path = require('path')
var merge = require('webpack-merge')
var baseConfig = require('./webpack.base')
var getEntries = require('./getEntries')
var hotMiddlewareScript = 'webpack-hot-middleware/client?reload=true';
var assetsInsert = require('./assetsInsert')
module.exports = merge(baseConfig, {
entry: getEntries(hotMiddlewareScript),
devtool: '#eval-source-map',
output: {
filename: './[name].[hash].js',
path: path.resolve('./dist'),
publicPath:'./dist'
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"'
}
}),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new assetsInsert()
]
})
说说这个设置中的一些难点:
1、getEntries 是用来设置进口文件,平常许多人是本身手写,或许SPA页面,只要一个进口, 很轻易就写出来,然则公司中,许多状况,是须要多进口,也就是多路由的Url,这个时刻进口的设置就比较贫苦,我这里是放零丁一个文件内里设置,我们公司是靠划定来实行,也就是一个文件夹一切的main.js都认为是进口文件,其他都疏忽。
function getEntry(hotMiddlewareScript) {
var pattern = paths.dev.js + 'project/**/main.js';
var array = glob.sync(pattern);
var newObj = {};
array.map(function(el){
var reg = new RegExp('project/(.*)/main.js','g');
reg.test(el);
if (hotMiddlewareScript) {
newObj[RegExp.$1] = [el, hotMiddlewareScript];
} else {
newObj[RegExp.$1] = el;
}
});
return newObj;
}
2、assetsInsert 是用来做模板替代的,一个小插件把template内里的值替代成打包后的css或许js。
三、打包环境设置–production
var webpack = require('webpack');
var path = require('path')
var merge = require('webpack-merge')
var baseConfig = require('./webpack.base')
var getEntries = require('./getEntries')
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var assetsInsert = require('./assetsInsert')
var productionConf = merge(baseConfig, {
entry: getEntries(),
output: {
filename: './[name].[hash].js',
path: path.resolve('./public/dist'),
publicPath: './'
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new ExtractTextPlugin('./[name].[hash].css', {
allChunks: true
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new webpack.optimize.OccurenceOrderPlugin(),
new assetsInsert()
]
})
productionConf.module.loaders = [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
}, {
test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url?limit=8192&context=client&name=[path][name].[hash:7].[ext]'
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style', 'css'),
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style', 'css!sass')
}]
module.exports = productionConf
基础跟开辟的差不多,差异在于:
1、运用ExtractTextPlugin 来打包css,所以要干掉本来base的loaders,从新写了一个,在最下面。
2、UglifyJsPlugin 给js紧缩代码。其他没有什么好诠释的了,一样的。
四、构建敕令
require('shelljs/global')
env.NODE_ENV = 'production'
var ora = require('ora')
var webpack = require('webpack')
var webpackConfig = require('./webpack.production.config')
var spinner = ora('building for production...')
spinner.start()
var staticPath = __dirname + '/../public/dist/'
rm('-rf', staticPath)
mkdir('-p', staticPath)
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n')
})
写一个build.js,然后在package.json内里增加 script 参数
"build": "node build.js"//这里记得写本身build.js途径
甜点(马卡龙)–有点腻
上面的设置是能够变动的,比方你在loaders 内里加上
{
test: /\.vue$/,
loader: 'vue'
}
就能够变成支撑.vue文件的vuejs打包构建,同理,修改下支撑jsx,和增加一些reactjs的module,就能够用来跑Reactjs的东西。
另有能够随便变动Css预编译器的范例,用你本身喜好就行,或许跟我们前面提到的要领,把一切范例都设置上,
var path = require('path')
var config = require('../config')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
exports.assetsPath = function (_path) {
return path.posix.join(config.build.assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
// generate loader string to be used with extract text plugin
function generateLoaders (loaders) {
var sourceLoader = loaders.map(function (loader) {
var extraParamChar
if (/\?/.test(loader)) {
loader = loader.replace(/\?/, '-loader?')
extraParamChar = '&'
} else {
loader = loader + '-loader'
extraParamChar = '?'
}
return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')
}).join('!')
if (options.extract) {
return ExtractTextPlugin.extract('vue-style-loader', sourceLoader)
} else {
return ['vue-style-loader', sourceLoader].join('!')
}
}
// http://vuejs.github.io/vue-loader/configurations/extract-css.html
return {
css: generateLoaders(['css']),
postcss: generateLoaders(['css']),
less: generateLoaders(['css', 'less']),
sass: generateLoaders(['css', 'sass?indentedSyntax']),
scss: generateLoaders(['css', 'sass']),
stylus: generateLoaders(['css', 'stylus']),
styl: generateLoaders(['css', 'stylus'])
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
var output = []
var loaders = exports.cssLoaders(options)
for (var extension in loaders) {
var loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
loader: loader
})
}
return output
}
这就是把一切的css预编译的都加到设置内里了。
总结下–买单啦
Webpack多种多样,就算一个loaders都有好几种差异的设置,让人非常头疼,最症结的是许多插件本身的文档也不清不楚,弄得人人都很渺茫,我的履历就是多试多测,本身多写一写,看敕令行打印的毛病,去找缘由,不要一看到报错就慌了,许多新手最轻易出错就是一看到报错就疑心人生了,肯定要看报错纪录,平常都有提醒,根据提醒去处理响应题目就好啦。
下一章我们讲Nodejs的东东。