基于Vue CLI 3的webpack配置简解

    最近在学习写TypeScript时,tsc编译后ts文件老是报变量占用的错误,后来配置tsconfig.js编译到不同的目录可以了,但是每次更改都要手动编译好麻烦,就想自己配置一个webpack开发环境,之前用脚手架都不清楚具体配置,参考Vue脚手架配置,这篇博文也是基于Vue的配置总结。

npm命令

    回忆一下我们在使用webpack的时候,打包的时候一般命令都是 webpack ... 或者是 webpack-dev-server ... 来打包资源,我们在使用Vue脚手架的时候一般使用两个命令,一个是 npm run dev,一个是 npm run build。先来说 npm run命令是个什么东西,每当我们执行npm run命令的时候,就会新建一个shell,他会将当前目录node_modules/.bin加入path变量中,那在package.json中使用scripts来定义脚本,来看一下Vue是怎么配置dev和build的

 "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js,
    "start": "npm run dev",
    "build": "node build/build.js"
  },

我们在运行npm run dev的时候,可以理解新建shell然后执行了webpack-dev-server *** 命令,关于后边的配置项后面再说。我们看到start中配置了的npm run dev,因为npm run start可以简写成 npm start比较简洁,那我们就可以知道

npm run dev = npm start = npm run start = webapck-dev-server  --inline --progress --config build/webpack.dev.conf.js

那么npm run build应该更好理解了,就是执行了 node build/build.js,关于build.js里面做了什么后边再说。想要更详细了解npm可以点击npm scripts 使用指南

webpack的配置文件

    webpack有两种使用方式,终端或Node.js,无论那种方式都需要传递一个配置对象(configuration object),很好的是Vue CLI两种方式都用了,首先来看dev模式下的配置文件。

"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 0.0.0.0"

     webpack-dev-server是在开发过程中使用的,不仅可以启动服务供你访问页面,还能进行模块热替换,本篇只讨论简单配置,因为复杂的我也需学习。对于dev-server有很多选项能控制其行为,一种方式是在命令行后,如上面的--inline、--progress,另一种方式就是在配置文件中体现,关于更多配置项有兴趣请点击开发中 Server。我们自己搭建webpack的时候知道,配置项默认是webpack.config.js,那在dev命令行中 --config的作用是更改了默认配置文件,为当前目录下build/webpack.dev.conf.js。在我们自动搭建的项目中,大家都会看到以下目录

大致先说一下build下每个文件,上文我们说过npm run build就是执行了 node build/build.js,所以我们在输出代码时候执行的就是上图中的build.js文件,webpack.base.conf.js如其名他就是一个基础配置文件,根据用户使用条件不同又加了两个webpack.dev.conf.js开发时的配置文件和webpack.prod.conf.js可以理解成生产配置文件。先说开发中的webpack.base.conf.js

//webpack.base.conf.js 省略的很多配置内容
module.exports = {
  context: path.resolve(__dirname, '../'),
  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: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },
  module: {
    rules: [...]
     
  },
  node: {
    ...
  },
};

可以看到基础项里面就是我们自己搭建时候写的入口、出口、loader、插件等基础项,

//由于不想篇幅过长,省略了很多不相关的代码
...
const config = require('../config')
const merge = require('webpack-merge')
...
//引入了base.conf文件 
const baseWebpackConfig = require('./webpack.base.conf')
const HtmlWebpackPlugin = require('html-webpack-plugin')
...
//看到merge就知道是将后边的配置项和基准baseWebpackConfig合并
const devWebpackConfig = merge(baseWebpackConfig, {
  ...
  devServer: {
    clientLogLevel: 'warning',
    historyApiFallback: {
      rewrites: [
        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
      ],
    },
    hot: true,
    contentBase: false, // since we use CopyWebpackPlugin.
    compress: true,
    host: HOST || config.dev.host,
    port: PORT || config.dev.port,
    open: config.dev.autoOpenBrowser,
    overlay: config.dev.errorOverlay
      ? { warnings: false, errors: true }
      : false,
    publicPath: config.dev.assetsPublicPath,
    proxy: config.dev.proxyTable,
    quiet: true, // necessary for FriendlyErrorsPlugin
    watchOptions: {
      poll: config.dev.poll,
    }
  },
  plugins: [
    ...
    //使用webpack-dev-server的主要插件
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
    ...
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    }),
    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.dev.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ]
})

在dev.conf.js中加入了很多webpack-dev-server的配置项,可以看到最开始引入了const config = require('../config') ,我们可以看到在build同级目录下存在一个config(可在上截图中看到),在dev配置文件中引入了这个文件夹,那我们打开它下边的index.js

module.exports = {
  dev: {
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
      '/api': {  //代理地址
        target: 'http://**.110.130.**:8000',  //需要代理的地址
        changeOrigin: true,  //是否跨域
        secure: false,
        pathRewrite: {
          '^/api': ''
        }
      }},

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 8080, 
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    
    cacheBusting: true,

    cssSourceMap: true
  },

  build: {
    ...
  }
}

可以看到目录下又dev和build两个选项,那我们在webpack.dev.conf.js中可以看到

host: HOST || config.dev.host,
port: PORT || config.dev.port,

也就是说,在HOST和PORT没有设置的情况下,回去config.dev下取,这也是为什么我们开发中如果需要更改端口,需要更改config/index.js中dev下的host和port,对于各个配置项的作用还是建议大家取webpack官网上看一下。写写感觉篇幅有点长了,在简单说一下build的,其实原理和开发一下,只不过有些配置选项更改了,感觉还要写一个解析配置项的文章?,我们已经知道了npm run build执行的是 node build/build.js 我们先来看一下build.js文件

'use strict'
require('./check-versions')()

process.env.NODE_ENV = 'production'

const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')

const spinner = ora('building for production...')
spinner.start()

rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
  if (err) throw err
  webpack(webpackConfig, (err, stats) => {
    spinner.stop()
    if (err) throw err
    process.stdout.write(stats.toString({
      colors: true,
      modules: false,
      children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
      chunks: false,
      chunkModules: false
    }) + '\n\n')

    if (stats.hasErrors()) {
      console.log(chalk.red('  Build failed with errors.\n'))
      process.exit(1)
    }

    console.log(chalk.cyan('  Build complete.\n'))
    console.log(chalk.yellow(
      '  Tip: built files are meant to be served over an HTTP server.\n' +
      '  Opening index.html over file:// won\'t work.\n'
    ))
  })
})

这个就直接全粘过来了,之前我们提到过,wenpack又两种执行方式,对于dev来说是执行了shell命令,那对于build来说是执行了node的一种方式

const webpack = require("webpack");

webpack({
  // 配置对象
}, (err, stats) => {
  if (err || stats.hasErrors()) {
    // 在这里处理错误
  }
  // 处理完成
});

build,js中webpack传入了webpackConfig = require('./webpack.prod.conf'),那么它的配置就是base+prod的merge,通过node的内置对象process将结果输出到控制台,关于配置文件中插件和配置项的作用,如果有机会在进行深入的解读,希望这篇文章对你有所帮助。

   在补充一点,不同于webapck会输出可见的文件,webpack-dev-server输出的文件并不可见,江湖传言是在内存当中,编译后的bundle.js你可以通过localhost:8080/bundle.js看到,最好的方式是引入HtmlWebpackPlugin插件,这样你编译后bundle.js就会插入到你的script标签中。我觉得个人对webpack还是只停留在使用阶段,本来标题是详解,后来想想还是改成简解(简单解释?)期望能研究一下更深入有意思对项目有帮助的东西。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值