国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

vue-cli中的webpack配置詳解

2019-11-19 15:18:46
字體:
來源:轉載
供稿:網友

版本號

  • vue-cli 2.8.1 (終端通過vue -V 可查看)
  • vue 2.2.2
  • webpack 2.2.1

目錄結構

├── README.md├── build│  ├── build.js│  ├── check-versions.js│  ├── dev-client.js│  ├── dev-server.js│  ├── utils.js│  ├── vue-loader.conf.js│  ├── webpack.base.conf.js│  ├── webpack.dev.conf.js│  └── webpack.prod.conf.js├── config│  ├── dev.env.js│  ├── index.js│  └── prod.env.js├── index.html├── package.json├── src│  ├── App.vue│  ├── assets│  │  └── logo.png│  ├── components│  │  └── Hello.vue│  └── main.js└── static

webpack配置

主要對build目錄下的webpack配置做詳細分析

webpack.base.conf.js

入口文件entry

entry: { app: '.src/main.js'}

輸出文件output

config的配置在config/index.js文件中

output: { path: config.build.assetsRoot, //導出目錄的絕對路徑 filename: '[name].js', //導出文件的文件名 publicPath: process.env.NODE_ENV === 'production'? config.build.assetsPublicPath : config.dev.assetsPublicPath //生產模式或開發模式下html、js等文件內部引用的公共路徑}

文件解析resolve

主要設置模塊如何被解析。

resolve: { extensions: ['.js', '.vue', '.json'], //自動解析確定的拓展名,使導入模塊時不帶拓展名 alias: {  // 創建import或require的別名  'vue$': 'vue/dist/vue.esm.js',   '@': resolve('src') }}

模塊解析module

如何處理項目不同類型的模塊。

module: { rules: [  {   test: //.vue$/, // vue文件后綴   loader: 'vue-loader', //使用vue-loader處理   options: vueLoaderConfig //options是對vue-loader做的額外選項配置  },  {   test: //.js$/, // js文件后綴   loader: 'babel-loader', //使用babel-loader處理   include: [resolve('src'), resolve('test')] //必須處理包含src和test文件夾  },  {   test: //.(png|jpe?g|gif|svg)(/?.*)?$/, //圖片后綴   loader: 'url-loader', //使用url-loader處理   query: { // query是對loader做額外的選項配置    limit: 10000, //圖片小于10000字節時以base64的方式引用    name: utils.assetsPath('img/[name].[hash:7].[ext]') //文件名為name.7位hash值.拓展名   }  },  {   test: //.(woff2?|eot|ttf|otf)(/?.*)?$/, //字體文件   loader: 'url-loader', //使用url-loader處理   query: {    limit: 10000, //字體文件小于1000字節的時候處理方式    name: utils.assetsPath('fonts/[name].[hash:7].[ext]') //文件名為name.7位hash值.拓展名   }  } ]}

注: 關于query 僅由于兼容性原因而存在。請使用 options 代替。

webpack.dev.conf.js

開發環境下的webpack配置,通過merge方法合并webpack.base.conf.js基礎配置

var merge = require('webpack-merge')var baseWebpackConfig = require('./webpack.base.conf')module.exports = merge(baseWebpackConfig, {})

模塊配置

module: { //通過傳入一些配置來獲取rules配置,此處傳入了sourceMap: false,表示不生成sourceMap rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) }

在util.styleLoaders中的配置如下

exports.styleLoaders = function (options) { var output = [] //定義返回的數組,數組中保存的是針對各類型的樣式文件的處理方式 var loaders = exports.cssLoaders(options) // 調用cssLoaders方法返回各類型的樣式對象(css: loader) for (var extension in loaders) { //循環遍歷loaders  var loader = loaders[extension] //根據遍歷獲得的key(extension)來得到value(loader)  output.push({   //   test: new RegExp('//.' + extension + '$'), // 處理的文件類型   use: loader //用loader來處理,loader來自loaders[extension]  }) } return output}

上面的代碼中調用了exports.cssLoaders(options),用來返回針對各類型的樣式文件的處理方式,具體實現如下

exports.cssLoaders = function (options) { options = options || {}  var cssLoader = {   loader: 'css-loader',  options: { //options是loader的選項配置    minimize: process.env.NODE_ENV === 'production', //生成環境下壓縮文件   sourceMap: options.sourceMap //根據參數是否生成sourceMap文件  } } function generateLoaders (loader, loaderOptions) { //生成loader  var loaders = [cssLoader] // 默認是css-loader  if (loader) { // 如果參數loader存在   loaders.push({    loader: loader + '-loader',    options: Object.assign({}, loaderOptions, { //將loaderOptions和sourceMap組成一個對象     sourceMap: options.sourceMap    })   })  }  if (options.extract) { // 如果傳入的options存在extract且為true   return ExtractTextPlugin.extract({ //ExtractTextPlugin分離js中引入的css文件    use: loaders, //處理的loader    fallback: 'vue-style-loader' //沒有被提取分離時使用的loader   })  } else {   return ['vue-style-loader'].concat(loaders)  } } return { //返回css類型對應的loader組成的對象 generateLoaders()來生成loader  css: generateLoaders(),  postcss: generateLoaders(),  less: generateLoaders('less'),  sass: generateLoaders('sass', { indentedSyntax: true }),  scss: generateLoaders('sass'),  stylus: generateLoaders('stylus'),  styl: generateLoaders('stylus') }}

插件配置

plugins: [ new webpack.DefinePlugin({ // 編譯時配置的全局變量  'process.env': config.dev.env //當前環境為開發環境 }), new webpack.HotModuleReplacementPlugin(), //熱更新插件 new webpack.NoEmitOnErrorPlugin(), //不觸發錯誤,即編譯后運行的包正常運行 new HtmlWebpackPlugin({ //自動生成html文件,比如編譯后文件的引入  filename: 'index.html', //生成的文件名  template: 'index.html', //模板  inject: true }), new FriendlyErrorsPlugin() //友好的錯誤提示]

webpack.prod.conf.js

生產環境下的webpack配置,通過merge方法合并webpack.base.conf.js基礎配置

module的處理,主要是針對css的處理

同樣的此處調用了utils.styleLoaders

module: { rules: utils.styleLoaders({  sourceMap: config.build.productionSourceMap,  extract: true }) }

輸出文件output

output: { //導出文件目錄 path: config.build.assetsRoot,  //導出的文件名 filename: utils.assetsPath('js/[name].[chunkhash].js'),  //非入口文件的文件名,而又需要被打包出來的文件命名配置,如按需加載的模塊 chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')}

插件plugins

var path = require('path')var utils = require('./utils')var webpack = require('webpack')var config = require('../config')var merge = require('webpack-merge')var baseWebpackConfig = require('./webpack.base.conf')var CopyWebpackPlugin = require('copy-webpack-plugin')var HtmlWebpackPlugin = require('html-webpack-plugin')var ExtractTextPlugin = require('extract-text-webpack-plugin')var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')var env = config.build.envplugins: [ new webpack.DefinePlugin({  'process.env': env //配置全局環境為生產環境 }), new webpack.optimize.UglifyJsPlugin({ //js文件壓縮插件  compress: { //壓縮配置   warnings: false // 不顯示警告  },  sourceMap: true //生成sourceMap文件 }), new ExtractTextPlugin({ //將js中引入的css分離的插件  filename: utils.assetsPath('css/[name].[contenthash].css') //分離出的css文件名 }), //壓縮提取出的css,并解決ExtractTextPlugin分離出的js重復問題(多個文件引入同一css文件) new OptimizeCSSPlugin(),  //生成html的插件,引入css文件和js文件 new HtmlWebpackPlugin({  filename: config.build.index, //生成的html的文件名  template: 'index.html', //依據的模板  inject: true, //注入的js文件將會被放在body標簽中,當值為'head'時,將被放在head標簽中  minify: { //壓縮配置   removeComments: true, //刪除html中的注釋代碼   collapseWhitespace: true, //刪除html中的空白符   removeAttributeQuotes: true //刪除html元素中屬性的引號  },  chunksSortMode: 'dependency' //按dependency的順序引入 }), //分離公共js到vendor中 new webpack.optimize.CommonsChunkPlugin({  name: 'vendor', //文件名  minChunks: functions(module, count) { // 聲明公共的模塊來自node_modules文件夾   return (module.resource && //.js$/.test(module.resource) && module,resource.indexOf(path.join(__dirname, '../node_modules')) === 0)  } }), //上面雖然已經分離了第三方庫,每次修改編譯都會改變vendor的hash值,導致瀏覽器緩存失效。原因是vendor包含了webpack在打包過程中會產生一些運行時代碼,運行時代碼中實際上保存了打包后的文件名。當修改業務代碼時,業務代碼的js文件的hash值必然會改變。一旦改變必然會導致vendor變化。vendor變化會導致其hash值變化。 //下面主要是將運行時代碼提取到單獨的manifest文件中,防止其影響vendor.js new webpack.optimize.CommonsChunkPlugin({  name: 'mainifest',  chunks: ['vendor'] }), // 復制靜態資源,將static文件內的內容復制到指定文件夾 new CopyWebpackPlugin([{  from: path.resolve(__dirname, '../static'),  to: config.build.assetsSubDirectory,  ignore: ['.*'] //忽視.*文件 }])]

額外配置

if (config.build.productionGzip) { //配置文件開啟了gzip壓縮  //引入壓縮文件的組件,該插件會對生成的文件進行壓縮,生成一個.gz文件 var CompressionWebpackPlugin = require('compression-webpack-plugin')  webpackConfig.plugins.push(  new CompressionWebpackPlugin({   asset: '[path].gz[query]', //目標文件名   algorithm: 'gzip', //使用gzip壓縮   test: new RegExp( //滿足正則表達式的文件會被壓縮    '//.(' +    config.build.productionGzipExtensions.join('|') +    ')$'   ),   threshold: 10240, //資源文件大于10240B=10kB時會被壓縮   minRatio: 0.8 //最小壓縮比達到0.8時才會被壓縮  }) )}

npm run dev

有了上面的配置之后,下面看看運行命令npm run dev發生了什么

在package.json文件中定義了dev運行的腳本

"scripts": {  "dev": "node build/dev-server.js",  "build": "node build/build.js"},

當運行npm run dev命令時,實際上會運行dev-server.js文件

該文件以express作為后端框架

// nodejs環境配置var config = require('../config')if (!process.env.NODE_ENV) { process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)}var opn = require('opn') //強制打開瀏覽器var path = require('path')var express = require('express')var webpack = require('webpack')var proxyMiddleware = require('http-proxy-middleware') //使用代理的中間件var webpackConfig = require('./webpack.dev.conf') //webpack的配置var port = process.env.PORT || config.dev.port //端口號var autoOpenBrowser = !!config.dev.autoOpenBrowser //是否自動打開瀏覽器var proxyTable = config.dev.proxyTable //http的代理urlvar app = express() //啟動expressvar compiler = webpack(webpackConfig) //webpack編譯//webpack-dev-middleware的作用//1.將編譯后的生成的靜態文件放在內存中,所以在npm run dev后磁盤上不會生成文件//2.當文件改變時,會自動編譯。//3.當在編譯過程中請求某個資源時,webpack-dev-server不會讓這個請求失敗,而是會一直阻塞它,直到webpack編譯完畢var devMiddleware = require('webpack-dev-middleware')(compiler, { publicPath: webpackConfig.output.publicPath, quiet: true})//webpack-hot-middleware的作用就是實現瀏覽器的無刷新更新var hotMiddleware = require('webpack-hot-middleware')(compiler, { log: () => {}})//聲明hotMiddleware無刷新更新的時機:html-webpack-plugin 的template更改之后compiler.plugin('compilation', function (compilation) { compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {  hotMiddleware.publish({ action: 'reload' })  cb() })})//將代理請求的配置應用到express服務上Object.keys(proxyTable).forEach(function (context) { var options = proxyTable[context] if (typeof options === 'string') {  options = { target: options } } app.use(proxyMiddleware(options.filter || context, options))})//使用connect-history-api-fallback匹配資源//如果不匹配就可以重定向到指定地址app.use(require('connect-history-api-fallback')())// 應用devMiddleware中間件app.use(devMiddleware)// 應用hotMiddleware中間件app.use(hotMiddleware)// 配置express靜態資源目錄var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)app.use(staticPath, express.static('./static'))var uri = 'http://localhost:' + port//編譯成功后打印uridevMiddleware.waitUntilValid(function () { console.log('> Listening at ' + uri + '/n')})//啟動express服務module.exports = app.listen(port, function (err) { if (err) {  console.log(err)  return } // 滿足條件則自動打開瀏覽器 if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {  opn(uri) }})

npm run build

由于package.json中的配置,運行此命令后會執行build.js文件

process.env.NODE_ENV = 'production' //設置當前環境為productionvar ora = require('ora') //終端顯示的轉輪loadingvar rm = require('rimraf') //node環境下rm -rf的命令庫var path = require('path') //文件路徑處理庫var chalk = require('chalk') //終端顯示帶顏色的文字var webpack = require('webpack') var config = require('../config') var webpackConfig = require('./webpack.prod.conf') //生產環境下的webpack配置// 在終端顯示ora庫的loading效果var spinner = ora('building for production...')spinner.start()// 刪除已編譯文件rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { if (err) throw err //在刪除完成的回調函數中開始編譯 webpack(webpackConfig, function (err, stats) {  spinner.stop() //停止loading  if (err) throw err    // 在編譯完成的回調函數中,在終端輸出編譯的文件  process.stdout.write(stats.toString({   colors: true,   modules: false,   children: false,   chunks: false,   chunkModules: false  }) + '/n/n') })})

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宾阳县| 岫岩| 永登县| 乌什县| 龙井市| 莒南县| 尤溪县| 津南区| 枣阳市| 苍溪县| 齐河县| 伊川县| 玛多县| 高平市| 云林县| 沽源县| 司法| 罗平县| 保靖县| 临朐县| 巴马| 常山县| 海晏县| 平江县| 白银市| 天台县| 德州市| 宣恩县| 雷波县| 云林县| 大邑县| 昭通市| 南城县| 桃源县| 大宁县| 萨嘎县| 佳木斯市| 手机| 柘荣县| 集贤县| 柘荣县|