从vue-cli中学习webpack的配置

2 篇文章 0 订阅
1 篇文章 0 订阅

webpack 配置

webpack 3.6.0

build 目录
webpack.base.conf.js
webpack.dev.conf.js
webpack.prod.conf.js
webpack.test.conf.js

分别对应着公共配置项、开发、生产和测试环境的配置。然后使用webpack-merge把这些公共配置项和环境特定的配置项merge起来,成为一个完整的配置项。

'use strict'
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')

const devWebpackConfig = merge(baseWebpackConfig, {
   ...
})

这三个环境不仅有一部分配置不同,更关键的是,每个配置中用 webpack.DefinePlugin 向代码注入了 NODE_ENV 这个环境变量。

这个变量在不同环境下有不同的值,比如 dev 环境下就是 development。这些环境变量的值是在 config 文件夹下的配置文件中定义的。Webpack 首先从配置文件中读取这个值,然后注入。比如这样:

// build/webpack.dev.conf.js
plugins: [
  new webpack.DefinePlugin({
    'process.env': require('../config/dev.env.js')
  }),
]

// config/dev.env.js
module.exports ={
  NODE_ENV: '"development"'
}

这种区分不同的环境,并给环境变量设置不同的值的实践,让我们开启了编译时按环境对代码进行针对性优化的可能。

html在webpack中的配置

以commonJS模块化机制向外输出

//在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
  },

HTML打包我们需要安装引入html-webpack-plugin

const HtmlWebpackPlugin = require('html-webpack-plugin');

//module.exports里配置我们的plugins(插件):
  plugins: [
    new webpack.DefinePlugin({
      'process.env': require('../config/dev.env')
    }), 
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
    new webpack.NoEmitOnErrorsPlugin(),
    // https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({ //将模板的头部和尾部添加css和js模板,dist 目录发布到服务器上,项目包。可以直接上线
      filename: 'index.html',
      template: 'index.html',
      inject: true
    }),
  ]

配置好后,在终端输入npm run dev后webpack将我们的html打包好并且自动将我们的js引进来

css在webpack的配置
extract-text-webpack-plugin

在执行npm run build之后并没有我们的css,因为webpack配置里 css in js。即打包时是吧我们的css打包进js里的。所以引入extract-text-webpack=p;ugin插件将css从js里面剥离出来.
require机制:在我们打包的过程中,文件的引用require按照顺序来打包。这就是文件依赖的机制。

js在webpack中的配置

由于很多浏览器并不支持es6.所以需要引用babel将es6代码编译成es5.
1. 新建.babelrc文件进行配置。
2. 安装babel并在webpack.config.base.js里的modules/rules下进行配置

babel-loader babel-core babel-preset-env //babel基本的三个文件
{
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test')]
      },
图片资源在webpack中的配置
  1. src目录下新建一个assets文件放置图片。安装file-loader根据文件地址加载文件
  2. 在webpack.config.base.js里的module/rules
{
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
别名(@)在webpack中的配置

在vue-cli中我们经常@一个文件夹,其意思就是在src目录下,现在我们去一探究竟。在exports下,注意跟module同级。

 resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'src': path.resolve(__dirname, '../src'),
      'common': path.resolve(__dirname, '../src/common'),
      'components': path.resolve(__dirname, '../src/components')
    }
  },
其他一些静态资源在webpack中的配置
  1. src下其他的文件直接复制到dist目录下,并不是每个文件都需要打包处理的,很多资源可能直接就可以复制过去。使用我们的 CopyWebpackPlugin插件

  2. 引用框架 jquery lodash工具库是很多组件会复用的,省去了import。使用webpack.ProvidePlugin插件

npm run dev 发生了什么

在vue-cli中我们启动监听npm run dev可以时时监控我们src下文件的改动,那他到底发生了什么呢。在webpack里其实创建了一个node进程,通过webpack-dev-server其内部封装了一个node的express模块,其配置项如下:

//package.json中的配置
"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "lint": "eslint --ext .js,.vue src",
    "build": "node build/build.js"
  },

  //webpack.dev.conf.js中的配置
   devServer: {
    before(app) {
      app.get('/api/seller', function(req, res) {
        res.json({
          errno: 0,
          data: seller
        })
      });
      app.get('/api/goods', function(req, res) {
        res.json({
          errno: 0,
          data: goods
        })
      });
      app.get('/api/ratings', function(req, res) {
        res.json({
          errno: 0,
          data: ratings
        })
      });
    }, 服务于webpack-dev-server  内部封装了一个express
webpack4 的变化

详细可见:https://juejin.im/post/5b304f1f51882574c72f19b0

开发和生产环境的区分

Webpack4引入了mode这个选项。这个选项的值可以是development或者production.

设置了 mode 之后会把 process.env.NODE_ENV 也设置为 development 或者 production。然后在 production 模式下,会默认开启 UglifyJsPlugin 等等一堆插件

Webpack 4 下如果需要一个 test 环境,那 test 环境的 mode 也是 development。因为 mode 只有开发和生产两种,测试环境应该是属于开发阶段。

Code Splitting

Webpack 4 下还有一个大改动,就是废弃了 CommonsChunkPlugin,引入了 optimization.splitChunks 这个选项。

optimization.splitChunks 默认是不用设置的。如果 mode 是 production,那 Webpack 4 就会开启 Code Splitting。

默认 Webpack 4 只会对按需加载的代码做分割。如果我们需要配置初始加载的代码也加入到代码分割中,可以设置 splitChunks.chunks 为 'all'
Long-term caching

Long-term caching 这里,基本的操作和 Webpack 3 是一样的。不过 Webpack 3 的 Long-term caching 在操作的时候,有个小问题,这个问题是关于 chunk 内容和 hash 变化不一致的:
在公共代码 Vendor 内容不变的情况下,添加 entry,或者 external 依赖,或者异步模块的时候,Vendor 的 hash 会改变。

Webpack 内部维护了一个自增的 id,每个 chunk 都有一个 id。所以当增加 entry 或者其他类型 chunk 的时候,id 就会变化,导致内容没有变化的 chunk 的 id 也发生了变化。

应对方案是,使用 webpack.NamedChunksPlugin 把 chunk id 变为一个字符串标识符,这个字符包一般就是模块的相对路径。这样模块的 chunk id 就可以稳定下来

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值