Run Multiple Webpack Configs Sequentially
https://www.viget.com/articles/run-multiple-webpack-configs-sequentially/
const path = require('path');
const serverConfig = {
entry: './src/b.ts'
}
const config2 = {
entry: './src/index.ts',
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
"devServer": {
"port": 8083
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
module.exports = [config2, serverConfig]
---------------------------------------------
When one webpack config depends on the outcome of another, running the configurations sequentially can save the day.
I have a webpack build process, and it is has two isolated configurations (one for my server-side build, and another for my client-side build). Here's an incredibly simplified example:
// webpack.config.js
const clientConfig = {
entry: './src/client/index.js',
}
const serverConfig = {
entry: './src/server/index.js'
}
module.exports = [clientConfig, serverConfig]
Everything clicked together quickly and easily, webpack is able to run these two builds and export different bundles for each environment. But then, of course, the joyous innocence of the early days faded as we added more functionality.
The Rub
We pulled in a library called React Loadable (side note: fantastic library), which comes with a webpack plugin, which can generate a file during the build. This file generation is defined in the client config, but application code within the server depends on that file. Because the file itself is a build artifact, we're not checking it into our source control, and thus the build must succeed without the up-front existence of this file.
// webpack.config.js
const { ReactLoadablePlugin } = require('react-loadable/webpack')
const clientConfig = {
entry: './src/client/index.js',
plugins: [
// This plugin creates the react-loadable.json file
new ReactLoadablePlugin({
filename: path.resolve(__dirname, 'react-loadable.json')
}),
]
}
const serverConfig = {
// This entry point makes use of the built react-loadable.json file
entry: './src/server/index.js'
}
module.exports = [clientConfig, serverConfig]
This is where things stop working. I've deduced that the configurations are being built in parallel, because even though the client configuration successfully creates the new file (I can see it in the build logs, and I can see those logs before I see any mention of the server build), the server build fails with a "I can't find that file!" error. If the file exists before the build runs, then everything flows smoothly, so the question became how to make it work without the pre-existence of that artifact.
The Solution
The internet had a few things to say about this. One option is to break apart the build and manually build each configuration in isolation. This requires some fiddling with your CLI usage, but does ensure that one config completely finishes before starting the new one. I was tempted to find a more streamlined solution, one that would allow me to run webpack the way that you'd expect.
What I ended up with was an extension of WebpackBeforeBuildPlugin which simply polled for the existence of the required file.
// WaitPlugin.js
const WebpackBeforeBuildPlugin = require('before-build-webpack')
const fs = require('fs')
class WaitPlugin extends WebpackBeforeBuildPlugin {
constructor(file, interval = 100, timeout = 10000) {
super(function(stats, callback) {
let start = Date.now()
function poll() {
if (fs.existsSync(file)) {
callback()
} else if (Date.now() - start > timeout) {
throw Error("Maybe it just wasn't meant to be.")
} else {
setTimeout(poll, interval)
}
}
poll()
})
}
}
module.exports = WaitPlugin
// webpack.config.js
const { ReactLoadablePlugin } = require('react-loadable/webpack')
const WaitPlugin = require('./WaitPlugin')
const clientConfig = {
entry: './src/client/index.js',
plugins: [
new ReactLoadablePlugin({
filename: path.resolve(__dirname, 'react-loadable.json')
}),
]
}
const serverConfig = {
entry: './src/server/index.js',
plugins: [
new WaitPlugin('react-loadable.json')
]
}
module.exports = [clientConfig, serverConfig]
Now, the server config will hang while the client config wraps up. Checking every 100 milliseconds (for a maximum of 10 seconds), the build will only proceed when the file in question exists.
I admit that I was hoping to be able to more definably run the multiple configuration builds in sequence, but this has certainly done the trick. If you've found another solution to this problem, we'd love to hear about it in the comments below!
Run Multiple Webpack Configs Sequentially的更多相关文章
- 【转帖】如何在redhat单机服务器上运行postgresql的多个实例(howto run multiple postgresql instance on one redhat server)
Running multiple PostgreSQL 9.2 Instances on one server in CentOS 6/RHEL 6/Fedora 原帖网站速度很慢,故转帖在此 Thi ...
- PHPFarm - How to run multiple versions of PHP on the same computer
How to Run Multiple Versions of PHP on One Server 转载:http://www.sitepoint.com/run-multiple-versions- ...
- TestNG – Run multiple test classes (suite test)
In this tutorial, we will show you how to run multiple TestNG test cases (classes) together, aka sui ...
- [Webpack] Create Separate webpack Configs for Development and Production with webpack-merge
The development and production modes in webpack optimize the output in different ways. In developmen ...
- React 和 ES6 工作流之 Webpack的使用(第六部分)
这是React和ECMAScript2015系列文章的最后一篇,我们将继续探索React 和 Webpack的使用. 下面是所有系列文章章节的链接: React . ES6 - 介绍(第一部分) Re ...
- webpack+react+antd 单页面应用实例
React框架已经火了好长一段时间了,再不学就out了! 对React还没有了解的同学可以看看我之前的一篇文章,可以快速简单的认识一下React.React入门最好的实例-TodoList 自己从开始 ...
- gulp + webpack + sass 学习
笔记: new webpack.optimize.CommonsChunkPlugin 核心作用是抽离公共代码,chunks:['index.js','main.js'] 另一个作用就是单独生成一个j ...
- webpack配置备份
package.json: { "name": "webpackTest", "version": "1.0.0", & ...
- [译]rabbitmq 2.4 Multiple tenants: virtual hosts and separation
我对rabbitmq学习还不深入,这些翻译仅仅做资料保存,希望不要误导大家. With exchanges, bindings, and queues under your belt, you mig ...
随机推荐
- Dnsmasq MacOS使用介绍
Dnsmasq MacOS使用介绍 问题: pc端开发时,需要在/etc/hosts里配置各种本地环境:当开发移动的界面时,除了使用浏览器的"手机模式"查看效果,还可以直接使用手机 ...
- c#通过socket判断服务器连接是否正常
判断Socket是否连接上,需要通过发包来确认. 之前确认都是调用调用socket的connected属性,然而该属性是上次的连接是否成功的结果,不及时. // 检查一个Socket是否可连接 pri ...
- linux下RAR和ZIP安装和使用
服务器没装rar,对于上传是压缩的文件来说,是个很大的问题. 源码安装rar: 1. 下载: wget http://www.rarlab.com/rar/rarlinux-x64-4.2.0.tar ...
- spring security进阶2 添加账户并对账户密码进行加密
目录 spring security 添加账户并对账户密码进行加密 一.原理分析 1.1加密原理 1.2加密后的登录过程 二.代码实现 2.1添加用户的页面如下, register.html 2.2c ...
- springboot实战日记(一)数据库基本信息
摘要:基于spring boot的后端实现,开发一个微信小程序点餐系统,主要是写写思路和遇到的问题以及分享读到的好文章. 项目分析: 1.角色划分,就是开有什么人使用这个系统,买家(手机端),卖家(p ...
- docker+k8s基础篇五
Docker+K8s基础篇(五) service资源介绍 A:service资源的工作特性 service的使用 A:service字段介绍 B:ClusterIP的简单使用 C:NodePort的简 ...
- python三大器之装饰器的练习
装饰器 加载顺序从下至上 执行顺序从上至下 ''' 多层装饰器 ''' def deco1(func): #func=deco2 def wrapper1(*args, **kwargs): '''t ...
- Ubuntu19.04 Help
Ubuntu Dock 为应用程序启用最小化操作,立即生效. $ gsettings set org.gnome.shell.extensions.dash-to-dock click-action ...
- 2. RDD编程
2.1 编程模型 在Spark中,RDD被表示为对象,通过对象上的方法调用来对RDD进行转换.经过一系列的transformations定义RDD之后,就可以调用actions触发RDD的计算,act ...
- tkinter学习笔记_05
10.菜单 menuber import tkinter as tk root = tk.Tk() root.title("xxx") root.geometry('200x100 ...