學習地址:javascript
http://blog.csdn.net/zaichuanguanshui/article/details/53610694 //配置參數意義css
http://blog.csdn.net/zaichuanguanshui/article/details/53611379 //經常使用插件html
出處: https://segmentfault.com/a/1190000006201049前端
上一篇文章介紹了目前前端比較流行的各類編輯器,以及各類流行的打包方式,最後給了一個Gulp的例子,這個例子仍是14年的時候寫的,還有一些能夠優化的空間,就不討論了,這篇文章主要講目前火熱的打包構建方式--Webpack的使用方式。vue
其實Webpack的入門指導文章很是多,配置方式也各有各樣,這裏我推薦題葉大神的入門級指南--Webpack 入門指迷,若是不知道Webpack是什麼或者不是很清楚各項配置含義的開發者,能夠看此文章掃掃盲。畢竟我這篇文章並非特別基礎。java
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;
解讀下這個基本配置:node
一、resolve 解析模塊依賴的時候,受影響的配置項。react
extensions 決定了哪些文件後綴在引用的時候能夠省略點,Webpack幫助你補全名稱。webpack
fallback 當webpack在 root(默認當前文件夾,配置時要絕對路徑) 和 modulesDirectories(默認當前文件夾,相對路徑)配置下面找不到相關modules,去哪一個文件夾下找modulesgit
alias 這個你們應該比較熟悉,requirejs之類的都有,就是別名,幫助你快速指向文件路徑,少寫很多代碼,並且不用關心層級關係, 須要注意的是:在scss之類的css預編譯中引用要加上~,以便於讓loader識別是別名引用路徑。
二、module 解析不一樣文件使用哪些loader,這個比較簡單,不少文章都有,就很少說了,注意的是,這裏的scss能夠換成你本身的預編譯器,例如:sass、less、stylus等,或者直接用postcss都行,固然還能夠用一種通用方法,後面補上。
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() ] })
說說這個配置中的一些難點:
一、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; }
二、assetsInsert 是用來作模板替換的,一個小插件把template裏面的值替換成打包後的css或者js。
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
基本跟開發的差很少,差異在於:
一、使用ExtractTextPlugin 來打包css,因此要幹掉原來base的loaders,從新寫了一個,在最下面。
二、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的東東。