日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
如何打造一個(gè)令人愉悅的前端開發(fā)環(huán)境(二)

前情提要

上一篇文章介紹了目前前端比較流行的各種編輯器,以及各種流行的打包方式,***給了一個(gè)Gulp的例子,這個(gè)例子還是14年的時(shí)候?qū)懙?,還有一些可以優(yōu)化的空間,就不討論了,這篇文章主要講目前火熱的打包構(gòu)建方式--Webpack的使用方式。

主菜--沒有開胃湯

其實(shí)Webpack的入門指導(dǎo)文章非常多,配置方式也各有各樣,這里我推薦題葉大神的入門級(jí)指南--Webpack 入門指迷,如果不知道Webpack是什么或者不是很清楚各項(xiàng)配置含義的開發(fā)者,可以看此文章掃掃盲。畢竟我這篇文章并不是特別基礎(chǔ)。

一、base.js

 
 
  1. var path = require('path') 
  2. var baseConfig = { 
  3.     resolve: { 
  4.         extensions: ['', '.js'], 
  5.         fallback: [path.join(__dirname, '../node_modules')], 
  6.         alias: { 
  7.             'src': path.resolve(__dirname, '../src'), 
  8.             'assets': path.resolve(__dirname, '../src/assets'), 
  9.             'components': path.resolve(__dirname, '../src/components') 
  10.         } 
  11.     }, 
  12.     module: { 
  13.         loaders: [{ 
  14.             test: /\.js$/, 
  15.             loader: 'babel', 
  16.             exclude: /node_modules/ 
  17.         }, { 
  18.             test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)(\?.*)?$/, 
  19.             loader: 'url?limit=8192&context=client&name=[path][name].[hash:7].[ext]' 
  20.         }, 
  21.         { 
  22.             test: /\.css$/, 
  23.             loader: 'style!css!autoprefixer', 
  24.         }, 
  25.         { 
  26.             test: /\.scss$/, 
  27.             loader: 'style!css!autoprefixer!sass' 
  28.         }] 
  29.     } 
  30. }; 
  31.  
  32. module.exports = baseConfig; 

解讀下這個(gè)基本配置:

1、resolve 解析模塊依賴的時(shí)候,受影響的配置項(xiàng)。

extensions 決定了哪些文件后綴在引用的時(shí)候可以省略點(diǎn),Webpack幫助你補(bǔ)全名稱。

fallback 當(dāng)webpack在 root(默認(rèn)當(dāng)前文件夾,配置時(shí)要絕對(duì)路徑) 和 modulesDirectories(默認(rèn)當(dāng)前文件夾,相對(duì)路徑)配置下面找不到相關(guān)modules,去哪個(gè)文件夾下找modules

alias 這個(gè)大家應(yīng)該比較熟悉,requirejs之類的都有,就是別名,幫助你快速指向文件路徑,少寫不少代碼,而且不用關(guān)心層級(jí)關(guān)系,需要注意的是:在scss之類的css預(yù)編譯中引用要加上~,以便于讓loader識(shí)別是別名引用路徑。

2、module 解析不同文件使用哪些loader,這個(gè)比較簡(jiǎn)單,很多文章都有,就不多說了,注意的是,這里的scss可以換成你自己的預(yù)編譯器,例如:sass、less、stylus等,或者直接用postcss都行,當(dāng)然還可以用一種通用方法,后面補(bǔ)上。

二、開發(fā)環(huán)境配置--config

 
 
  1. var webpack = require('webpack'); 
  2. var path = require('path') 
  3. var merge = require('webpack-merge') 
  4. var baseConfig = require('./webpack.base') 
  5. var getEntries = require('./getEntries') 
  6.  
  7. var hotMiddlewareScript = 'webpack-hot-middleware/client?reload=true'; 
  8.  
  9. var assetsInsert = require('./assetsInsert') 
  10.  
  11. module.exports = merge(baseConfig, { 
  12.   entry: getEntries(hotMiddlewareScript), 
  13.   devtool: '#eval-source-map', 
  14.   output: { 
  15.     filename: './[name].[hash].js', 
  16.     path: path.resolve('./dist'), 
  17.     publicPath:'./dist' 
  18.   }, 
  19.   plugins: [ 
  20.     new webpack.DefinePlugin({ 
  21.       'process.env': { 
  22.         NODE_ENV: '"development"' 
  23.       } 
  24.     }), 
  25.     new webpack.optimize.OccurenceOrderPlugin(), 
  26.     new webpack.HotModuleReplacementPlugin(), 
  27.     new webpack.NoErrorsPlugin(), 
  28.     new assetsInsert() 
  29.   ] 
  30. }) 

說說這個(gè)配置中的一些難點(diǎn):

1、getEntries 是用來配置入口文件,一般很多人是自己手寫,或者SPA頁面,只有一個(gè)入口, 很容易就寫出來,但是公司中,很多情況,是需要多入口,也就是多路由的Url,這個(gè)時(shí)候入口的配置就比較麻煩,我這里是放單獨(dú)一個(gè)文件里面配置,我們公司是靠規(guī)定來執(zhí)行,也就是一個(gè)文件夾所有的main.js都認(rèn)為是入口文件,其他都忽略。

 
 
  1. function getEntry(hotMiddlewareScript) { 
  2.     var pattern = paths.dev.js + 'project/**/main.js'; 
  3.     var array = glob.sync(pattern); 
  4.     var newObj = {}; 
  5.  
  6.     array.map(function(el){ 
  7.         var reg = new RegExp('project/(.*)/main.js','g'); 
  8.         reg.test(el); 
  9.         if (hotMiddlewareScript) { 
  10.             newObj[RegExp.$1] = [el, hotMiddlewareScript]; 
  11.         } else { 
  12.             newObj[RegExp.$1] = el; 
  13.         } 
  14.     }); 
  15.     return newObj; 

2、assetsInsert 是用來做模板替換的,一個(gè)小插件把template里面的值替換成打包后的css或者js。

三、打包環(huán)境配置--production

 
 
  1. var webpack = require('webpack'); 
  2. var path = require('path') 
  3. var merge = require('webpack-merge') 
  4. var baseConfig = require('./webpack.base') 
  5. var getEntries = require('./getEntries') 
  6. var ExtractTextPlugin = require('extract-text-webpack-plugin'); 
  7. var assetsInsert = require('./assetsInsert') 
  8.  
  9. var productionConf = merge(baseConfig, { 
  10.     entry: getEntries(), 
  11.     output: { 
  12.         filename: './[name].[hash].js', 
  13.         path: path.resolve('./public/dist'), 
  14.         publicPath: './' 
  15.     }, 
  16.     plugins: [ 
  17.         new webpack.DefinePlugin({ 
  18.             'process.env': { 
  19.                 NODE_ENV: '"production"' 
  20.             } 
  21.         }), 
  22.         new ExtractTextPlugin('./[name].[hash].css', { 
  23.             allChunks: true 
  24.         }), 
  25.         new webpack.optimize.UglifyJsPlugin({ 
  26.             compress: { 
  27.                 warnings: false 
  28.             } 
  29.         }), 
  30.         new webpack.optimize.OccurenceOrderPlugin(), 
  31.         new assetsInsert() 
  32.     ] 
  33. }) 
  34.  
  35. productionConf.module.loaders = [ 
  36.              { 
  37.                 test: /\.js$/, 
  38.                 loader: 'babel', 
  39.                 exclude: /node_modules/ 
  40.             }, { 
  41.                 test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)(\?.*)?$/, 
  42.                 loader: 'url?limit=8192&context=client&name=[path][name].[hash:7].[ext]' 
  43.             }, 
  44.             { 
  45.                 test: /\.css$/, 
  46.                 loader: ExtractTextPlugin.extract('style', 'css'), 
  47.             }, 
  48.             { 
  49.                 test: /\.scss$/, 
  50.                 loader: ExtractTextPlugin.extract('style', 'css!sass') 
  51.             }] 
  52.  
  53. module.exports = productionConf 

基本跟開發(fā)的差不多,差別在于:

1、使用ExtractTextPlugin 來打包c(diǎn)ss,所以要干掉原來base的loaders,重新寫了一個(gè),在最下面。

2、UglifyJsPlugin 給js壓縮代碼。其他沒有什么好解釋的了,一樣的。

四、構(gòu)建命令

 
 
  1. require('shelljs/global') 
  2. env.NODE_ENV = 'production' 
  3. var ora = require('ora') 
  4. var webpack = require('webpack') 
  5. var webpackConfig = require('./webpack.production.config') 
  6.  
  7. var spinner = ora('building for production...') 
  8. spinner.start() 
  9.  
  10. var staticPath = __dirname + '/../public/dist/' 
  11. rm('-rf', staticPath) 
  12. mkdir('-p', staticPath) 
  13.  
  14. webpack(webpackConfig, function (err, stats) { 
  15.   spinner.stop() 
  16.   if (err) throw err 
  17.   process.stdout.write(stats.toString({ 
  18.     colors: true, 
  19.     modules: false, 
  20.     children: false, 
  21.     chunks: false, 
  22.     chunkModules: false 
  23.   }) + '\n') 
  24. }) 

寫一個(gè)build.js,然后在package.json里面添加 script 參數(shù) 

 
 
  1. "build": "node build.js"http://這里記得寫自己build.js路徑 

甜點(diǎn)(馬卡龍)--有點(diǎn)膩

上面的配置是可以更改的,例如你在loaders 里面加上

 
 
  1.   test: /\.vue$/, 
  2.   loader: 'vue' 

就可以變成支持.vue文件的vuejs打包構(gòu)建,同理,修改下支持jsx,和添加一些reactjs的module,就可以用來跑Reactjs的東西。

還有可以隨意更改Css預(yù)編譯器的類型,用你自己喜歡就行,或者跟我們前面提到的方法,把所有類型都配置上,

 
 
  1. var path = require('path') 
  2. var config = require('../config') 
  3. var ExtractTextPlugin = require('extract-text-webpack-plugin') 
  4.  
  5. exports.assetsPath = function (_path) { 
  6.   return path.posix.join(config.build.assetsSubDirectory, _path) 
  7.  
  8. exports.cssLoaders = function (options) { 
  9.   options = options || {} 
  10.   // generate loader string to be used with extract text plugin 
  11.   function generateLoaders (loaders) { 
  12.     var sourceLoader = loaders.map(function (loader) { 
  13.       var extraParamChar 
  14.       if (/\?/.test(loader)) { 
  15.         loader = loader.replace(/\?/, '-loader?') 
  16.         extraParamChar = '&' 
  17.       } else { 
  18.         loader = loader + '-loader' 
  19.         extraParamChar = '?' 
  20.       } 
  21.       return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '') 
  22.     }).join('!') 
  23.  
  24.     if (options.extract) { 
  25.       return ExtractTextPlugin.extract('vue-style-loader', sourceLoader) 
  26.     } else { 
  27.       return ['vue-style-loader', sourceLoader].join('!') 
  28.     } 
  29.   } 
  30.  
  31.   // http://vuejs.github.io/vue-loader/configurations/extract-css.html 
  32.   return { 
  33.     css: generateLoaders(['css']), 
  34.     postcss: generateLoaders(['css']), 
  35.     less: generateLoaders(['css', 'less']), 
  36.     sass: generateLoaders(['css', 'sass?indentedSyntax']), 
  37.     scss: generateLoaders(['css', 'sass']), 
  38.     stylus: generateLoaders(['css', 'stylus']), 
  39.     styl: generateLoaders(['css', 'stylus']) 
  40.   } 
  41.  
  42. // Generate loaders for standalone style files (outside of .vue) 
  43. exports.styleLoaders = function (options) { 
  44.   var output = [] 
  45.   var loaders = exports.cssLoaders(options) 
  46.   for (var extension in loaders) { 
  47.     var loader = loaders[extension] 
  48.     output.push({ 
  49.       test: new RegExp('\\.' + extension + '$'), 
  50.       loader: loader 
  51.     }) 
  52.   } 
  53.   return output 

這就是把所有的css預(yù)編譯的都加到配置里面了。

總結(jié)下--買單啦

Webpack多種多樣,就算一個(gè)loaders都有好幾種不同的配置,讓人很是頭疼,最關(guān)鍵的是很多插件自己的文檔也不清不楚,弄得大家都很迷茫,我的經(jīng)驗(yàn)就是多試多測(cè),自己多寫一寫,看命令行打印的錯(cuò)誤,去找原因,不要一看到報(bào)錯(cuò)就慌了,很多新手最容易犯錯(cuò)就是一看到報(bào)錯(cuò)就懷疑人生了,一定要看報(bào)錯(cuò)記錄,一般都有提示,按照提示去解決相應(yīng)問題就好啦。


網(wǎng)站名稱:如何打造一個(gè)令人愉悅的前端開發(fā)環(huán)境(二)
文章位置:http://www.5511xx.com/article/coepcjh.html