vue-cli+webpack配置(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zqh862735956/article/details/79610796

vue-cli+webpack配置分析

入口(package.json解析)

package.json即最初始化的配置文件
该配置文件

    //这里是指定了运行npm的缩写,npm run dev执行下面的文件,我理解是建立node环境
    "script": {
        //开发环境
        "dev": "node build/dev-server.js",
        //生产环境
        "build": "cross-env BABEL_ENV=production NODE_ENV=production node build/build.js"

    }

    //这个里面放的都是依赖的模块
    "dependencies": {

    }

生成

  • pack.json文件时可以自己写的,也可以去生成,生成方法

    //初始化
    npm init

    //安装依赖模块
    npm install

单个模块安装方法

这里一般都知道怎么安装,只是解释一下意思

$ npm install mint-ui --save
$ npm install mint-ui --save-dev
  • 这里表示安装mint-ui模块,–save 会把依赖包名称添加到 package.json 文件 dependencies 键下
  • –save-dev 则添加到 package.json 文件 devDependencies 键下

开发环境

开发环境的入口文件时

dev-server.js的配置

//配置文件
var config = require('../config')
//node环境无法判断当前是开发环境还是生产环境
//使用process.env.NODE_ENV作为当前的环境
if (!process.env.NODE_ENV) {
    process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}

//接口代理(关于vue的接口代理,我会单独总结一份出来)
var proxyMiddleware = require('http-proxy-middleware')
//指定开发环境
var webpackConfig = process.env.NODE_ENV === 'testing'
    //生产环境配置文件
    ? require('./webpack.prod.conf')
    //测试环境配置文件
    : require('./webpack.dev.conf')
// 指定端口号
var port = process.env.PORT || config.dev.port
// 是否设置自动打开浏览器,不设置默认false
var autoOpenBrowser = !!config.dev.autoOpenBrowser
//配置文件中http代理配置
var proxyTable = config.dev.proxyTable
// 启动 webpack 编译
var compiler = webpack(webpackConfig)
// 可以将编译后的文件暂存到内存中的插件
// https://github.com/webpack/webpack-dev-middleware
var devMiddleware = require('webpack-dev-middleware')(compiler, {
  // 公共路径,与webpack的publicPath一样
  publicPath: webpackConfig.output.publicPath,
  // 不打印
  quiet: true
})
// Hot-reload 热重载插件
// https://github.com/glenjamin/webpack-hot-middleware
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
  log: () => {}
})
// 当tml-webpack-plugin template更改之后,强制刷新浏览器
compiler.plugin('compilation', function (compilation) {
  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
    hotMiddleware.publish({ action: 'reload' })
    cb()
  })
})

// 将 proxyTable 中的请求配置挂在到启动的 express 服务上
Object.keys(proxyTable).forEach(function (context) {
  var options = proxyTable[context]
  // 如果options的数据类型为string,则表示只设置了url,
  // 所以需要将url设置为对象中的 target的值
  if (typeof options === 'string') {
    options = { target: options }
  }
  app.use(proxyMiddleware(options.filter || context, options))
})

//处理HTML5历史API的回退
// 如果不匹配就可以重定向到指定地址
app.use(require('connect-history-api-fallback')())

// 拼接 static 文件夹的静态资源路径
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
// 静态文件服务
app.use(staticPath, express.static('./static'))

var uri = 'http://localhost:' + port

// 编译成功后打印网址信息
devMiddleware.waitUntilValid(function () {
  console.log('> Listening at ' + uri + '\n')
})

//module.exports = app.listen(port, function (err) {
  if (err) {
    console.log(err)
    return
  }

  // 如果配置了自动打开浏览器,且不是测试环境,则自动打开浏览器并跳到我们的开发地址
  if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
    opn(uri)
  }
})

webpack配置

webpack.dev.conf.js开发环境配置

  • dev-server.js中使用了webpack.dev.conf.js文件,该文件是开发环境中webpack的配置入口。

    // 工具函数集合
    var utils = require('./utils')
    var webpack = require('webpack')
    // 配置文件
    var config = require('../config')
    // webpack配置合并插件
    var merge = require('webpack-merge')
    // webpack基础配置引入
    var baseWebpackConfig = require('./webpack.base.conf')
    // 自动生产html 并且注入到 .html文件中的插件
    var HtmlWebpackPlugin = require('html-webpack-plugin')
    // webpack 错误提示的插件
    var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
    
    // 讲 Hot-reload 热重载的客户端代码添加到 webpack,.base.conf对应的入口entry一起打包
    // vue热重载 即页面不刷新 更新组件
    Object.keys(baseWebpackConfig.entry).forEach(function (name) {
      baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
    })
    
    module.exports = merge(baseWebpackConfig, {
      module: {
        rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
      },
      // cheap-module-eval-source-map is faster for development
      devtool: '#cheap-module-eval-source-map',
      plugins: [
        new webpack.DefinePlugin({
          'process.env': config.dev.env
        }),
        // HotModule 插件在页面进行变更的时候只会重绘对应的页面模块,不会重绘整个 html 文件
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoEmitOnErrorsPlugin(),
        // 将 index.html 作为入口,注入 html 代码后生成 index.html文件
        new HtmlWebpackPlugin({
          filename: 'index.html',
          template: 'index.html',
          inject: true
        }),
        new FriendlyErrorsPlugin()
      ]
    })
    

webpavk.base.conf.js(webpack基础配置,开发测试生产共用)

// node自带的文件路径工具
var path = require('path')
// 工具函数集合
var utils = require('./utils')
  // 配置文件
var config = require('../config')
  // 工具函数集合
var vueLoaderConfig = require('./vue-loader.conf')

/**
 * 获得绝对路径
 * @method resolve
 * @param  {String} dir 相对于本文件的路径
 * @return {String}     绝对路径
 */
function resolve(dir) {
  return path.join(__dirname, '..', dir)
}

module.exports = {
  entry: {
    app: './src/main.js'
  },
  output: {
    // 编译输出的静态资源根路径
    path: config.build.assetsRoot,
    // 编译输出的文件名
    filename: '[name].js',
    // 正式发布环境下编译输出的上线路径的根路径
    publicPath: process.env.NODE_ENV === 'production' ?
      config.build.assetsPublicPath : config.dev.assetsPublicPath
  },
  resolve: {
    // 自动补全的扩展名
    extensions: ['.js', '.vue', '.json'],
    // 路径别名
    alias: {
      // 例如 import Vue from 'vue',会自动到 'vue/dist/vue.common.js'中寻找
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },
  module: {
    rules: [{
        // 审查 js 和 vue 文件
        // https://github.com/MoOx/eslint-loader
        test: /\.(js|vue)$/,
        loader: 'eslint-loader',
        // 表示预先处理
        enforce: "pre",
        include: [resolve('src'), resolve('test')],
        options: {
          formatter: require('eslint-friendly-formatter')
        }
      },
      {
        // 处理 vue文件
        // https://github.com/vuejs/vue-loader
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        // 编译 js
        // https://github.com/babel/babel-loader
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test')]
      },
      {
        // 处理图片文件
        // https://github.com/webpack-contrib/url-loader
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        query: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        // 处理字体文件
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        query: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  }
}

config/index.js

  • 是主要的配置文件,包含静态文件的路径、是否开启sourceMap等。其中,分为两个部分dev(开发环境的配置)和build(生产环境的配置)。

    // 详情见文档:https://vuejs-templates.github.io/webpack/env.html
    var path = require('path')
    
    module.exports = {
      // production 生产环境
      build: {
        // 构建环境
        env: require('./prod.env'),
        // 构建输出的index.html文件
        index: path.resolve(__dirname, '../dist/index.html'),
        // 构建输出的静态资源路径
        assetsRoot: path.resolve(__dirname, '../dist'),
        // 构建输出的二级目录
        assetsSubDirectory: 'static',
        // 构建发布的根目录,可配置为资源服务器域名或 CDN 域名
        assetsPublicPath: '/',
        // 是否开启 cssSourceMap
        productionSourceMap: true,
        // Gzip off by default as many popular static hosts such as
        // Surge or Netlify already gzip all static assets for you.
        // Before setting to `true`, make sure to:
        // npm install --save-dev compression-webpack-plugin
        // 默认关闭 gzip,因为很多流行的静态资源主机,例如 Surge、Netlify,已经为所有静态资源开启gzip
        productionGzip: false,
        // 需要使用 gzip 压缩的文件扩展名
        productionGzipExtensions: ['js', 'css'],
        // Run the build command with an extra argument to
        // View the bundle analyzer report after build finishes:
        // `npm run build --report`
        // Set to `true` or `false` to always turn it on or off
        // 运行“build”命令行时,加上一个参数,可以在构建完成后参看包分析报告
        // true为开启,false为关闭
        bundleAnalyzerReport: process.env.npm_config_report
      },
      // dev 开发环境
      dev: {
        // 构建环境
        env: require('./dev.env'),
        // 端口号
        port: 3333,
        // 是否自动打开浏览器
        autoOpenBrowser: true,
        assetsSubDirectory: 'static',
        // 编译发布的根目录,可配置为资源服务器域名或 CDN 域名
        assetsPublicPath: '/',
        // proxyTable 代理的接口(可跨域)
        // 使用方法:https://vuejs-templates.github.io/webpack/proxy.html
        proxyTable: {},
        // CSS Sourcemaps off by default because relative paths are "buggy"
        // with this option, according to the CSS-Loader README
        // (https://github.com/webpack/css-loader#sourcemaps)
        // In our experience, they generally work as expected,
        // just be aware of this issue when enabling this option.
        // 默认情况下,关闭 CSS Sourcemaps,因为使用相对路径会报错。
        // CSS-Loader README:https://github.com/webpack/css-loader#sourcemaps
        cssSourceMap: false
      }
    }
    

utils.js

utils.js也是一个被使用频率的文件,这个文件包含了三个工具函数:

  • 生成静态资源的路径
  • 生成 ExtractTextPlugin对象或loader字符串
  • 生成 style-loader的配置

    // node自带的文件路径工具
    var path = require('path')
    // 配置文件
    var config = require('../config')
    // 提取css的插件
    // https://github.com/webpack-contrib/extract-text-webpack-plugin
    var ExtractTextPlugin = require('extract-text-webpack-plugin')
    
    /**
     * 生成静态资源的路径
     * @method assertsPath
     * @param  {String}    _path 相对于静态资源文件夹的文件路径
     * @return {String}          静态资源完整路径
     */
    exports.assetsPath = function (_path) {
      var assetsSubDirectory = process.env.NODE_ENV === 'production'
        ? config.build.assetsSubDirectory
        : config.dev.assetsSubDirectory
        //  path.posix.join与path.join一样,不过总是以 posix 兼容的方式交互
      return path.posix.join(assetsSubDirectory, _path)
    }
    
    /**
     * 生成处理css的loaders配置
     * @method cssLoaders
     * @param  {Object}   options 生成配置
     *                            option = {
     *                              // 是否开启 sourceMap
     *                              sourceMap: true,
     *                              // 是否提取css
     *                              extract: true
     *                            }
     * @return {Object}           处理css的loaders配置对象
     */
    exports.cssLoaders = function (options) {
      options = options || {}
    
      var cssLoader = {
        loader: 'css-loader',
        options: {
          minimize: process.env.NODE_ENV === 'production',
          sourceMap: options.sourceMap
        }
      }
      /**
       * 生成 ExtractTextPlugin对象或loader字符串
       * @method generateLoaders
       * @param  {Array}        loaders loader名称数组
       * @return {String|Object}        ExtractTextPlugin对象或loader字符串
       */
      function generateLoaders (loader, loaderOptions) {
        var loaders = [cssLoader]
        if (loader) {
          loaders.push({
            // 例如,sass?indentedSyntax
            // 在?号前加上“-loader”
            loader: loader + '-loader',
            options: Object.assign({}, loaderOptions, {
              sourceMap: options.sourceMap
            })
          })
        }
    
        // extract为true时,提取css
        // 生产环境中,默认为true
        if (options.extract) {
          return ExtractTextPlugin.extract({
            use: loaders,
            fallback: 'vue-style-loader'
          })
        } else {
          return ['vue-style-loader'].concat(loaders)
        }
      }
    
      // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html
      return {
        css: generateLoaders(),
        postcss: generateLoaders(),
        less: generateLoaders('less'),
        sass: generateLoaders('sass', { indentedSyntax: true }),
        scss: generateLoaders('sass'),
        stylus: generateLoaders('stylus'),
        styl: generateLoaders('stylus')
      }
    }
    
    /**
     * 生成 style-loader的配置
     * style-loader文档:https://github.com/webpack/style-loader
     * @method styleLoaders
     * @param  {Object}     options 生成配置
     *                              option = {
     *                                // 是否开启 sourceMap
     *                                sourceMap: true,
     *                                // 是否提取css
     *                                extract: true
     *                              }
     * @return {Array}              style-loader的配置
     */
    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 + '$'),
          use: loader
        })
      }
      return output
    

    }

如有错误,欢迎指出

猜你喜欢

转载自blog.csdn.net/zqh862735956/article/details/79610796
今日推荐