乐趣区

关于前端:在webpack中这样分离环境和代码就好啦

后面的文章中,webpack.config.js 中蕴含本地调试和线上公布的所有配置,编译后的 bundle.js 蕴含所有的代码。

当我的项目变大、代码质变多、配置减少的时候,文件的可维护性会越来越差,是时候对他们进行拆散啦~

环境拆散

环境拆散次要是辨别本地和生产两种环境,本地调试须要能实时看到代码变动,而生产环境须要编译成指定的文件。

能够采纳两种形式

  • 开发环境和生产环境别离定义配置文件,在 package.json 中定义对应的指令
  • 开发环境和生产环境共用配置文件,通过参数来辨别环境

配置文件拆散

别离定义用于开发环境的配置文件 webpack.dev.js 和用于生产编译的 webpack.prod.js,再别离通过 npm run servenpm run build 来开启 devServer 和 编译操作

// package.json
"scripts": {
    "serve": "webpack serve --config ./config/webpack.dev.js",
    "build": "webpack --config ./config/webpack.prod.js",
  },

参数辨别

开发环境和生产环境都应用 webpack.common.js 文件,通过 package.json 中设置指令减少 –env 参数来辨别

"scripts": {
    "serve2": "webpack serve --config ./config/webpack.common.js --env development",
    "build2": "webpack --config ./config/webpack.common.js --env production"
  },

在 webpack.common.js 中 module.exports 定义为函数,就能够接管 env 传递的参数

将开发环境和生产环境都须要用到配置抽离进去放到一个对象中,别离应用的配置分抽离到独自文件,再通过 webpack-merge 工具来对配置代码进行合并。

// webpack.config.js
const {merge} = require('webpack-merge');
const devConfig = require('./webpack.dev');
const prodConfig = require('./webpack.prod');
const commonConfig = {... // 公共要用的配置}

module.exports = function (env) {
  // 赋值后可在 babel.config.js 中获取以后环境
  process.env.NODE_ENV = env.production ? 'production' : 'development';
  
  const config = env.production ? prodConfig : devConfig;
  return merge(commonConfig, config);
};

这样公共配置局部就能够对立治理

代码拆散

所有源代码都编译到一个文件中,会造成编译文件过大,一次性加载所有资源,加载速度慢,从性能的角度来思考,心愿晋升申请速度,以及当资源须要的时候再加载,那这个时候能够依据性能将源代码编译成多个文件。

代码拆散有三种形式

  • 多入口:通过 entry 配置多个入口,手动拆散代码
  • 避免反复:应用 Entry Dependencies 或 splitChunksPlugin 去重和拆散
  • 动静导入:通过 import 函数来拆散

多入口

// webpack.config.js
// 获取启动目录
const dirname = process.cwd();
const resolveApp = (folder) => path.resolve(dirname, folder);

module.exports = {
    entry: {
       index: './src/index.js',
       main: './src/main.js',
    },
    output: {filename: 'js/[name].js',
       path: resolveApp('./dist'),
    },  
    // ...
}

这样编译后就会依据入口生成两个 js 文件

避免反复

当存在公共的库时,多处援用可能会造成反复加载的问题。

Entry Dependencies

一种形式是定义 entry,将反复的依赖抽离独自编译成一个文件

splitChunksPlugin

另外就是能够应用 splitChunksPlugin,它曾经默认集成在 webpack 当中,通过 splitChunks 来设置属性,chunks 属性有三个值,用于定义拆散的场景。

  • async,默认状况,只有当代码进行异步操作时才会拆散
  • initial,同步代码会拆散
  • all,异步同步都会拆散
optimization: {
  chunkIds: 'named', // 规定文件的命名形式
  splitChunks: {chunks: 'all',},
},

定义了 splitChunks 中拆散代码形式之后,在 index.js 中应用到的 moment 和 lodash 都编译到 vendors 这个文件中

splitChunks 中还有其它的属性,用于规定编译的文件大小、文件名

  • minSize,默认 2 万字节,规定拆分进去的包最小值
  • maxSize,规定大于 maxSize 尺寸的包,拆分成不小于 minSize 的包
  • minChunks,示意援用的包至多被导入的次数
  • cacheGroup,缓存组,配置具体的编译规定

这些即便不设置,也都是有默认值的,下面将依赖打包的十分长的文件名 vendors 就是依照默认的设置生成的,在 webpack 的官网文档 中有介绍

也能够本人再进行定义,比方更改 打包依赖的文件名

动静导入

另外一种拆散的形式就是动静导入了,当应用资源时,才会下载并解析。

以下代码在 index.js 中引入 foo.js 和 baz.js

import('./foo');
import('./baz');

通过 import 函数动静导入的 js 被编译成两个独自的文件。

动静导入还能够通过魔法正文做一些配置

  • webpackChunkName 自定义编译后文件名
  • webpackPrefetch 在浏览器闲暇时提前下载资源
  • webpackPreload 和父 chunk 一起提前下载资源

在 import 函数中定义魔法正文

 import(/* webpackChunkName: 'foo'  */ /* webpackPreload: true */ './foo.js').then((result) => {console.log('foo 加载了', result, result.default);
  });

能够在看到 foo.js 第一次是在浏览器闲暇时下载资源,第二次是从缓存中获取资源

应用 prefetch 预获取的形式能够提前下载好资源,当应用的时候速度会绝对快一点,但这样会给入口文件渲染减少压力,所以还得视理论应用场景而定。

总结

  • webpack.config.js 中应用 module.exports 导出函数,通过参数来辨别编译环境,从而应用不同的 loader、plugin 和配置来解决开发、生产环境的资源。
  • 拆分代码能够通过多入口 entry、避免反复 splitChunksPlugin 和动静导入 lazy 函数的形式来操作,其中动静导入异步文件能够设置预加载或者预获取提前下载资源。

以上就是 webpack 环境和代码拆散的相干介绍,更多无关 webpack 的内容能够参考我其它的博文,继续更新中~

退出移动版