forked from pattern-lab/patternlab-node
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwebpack-server.js
More file actions
146 lines (129 loc) · 3.87 KB
/
webpack-server.js
File metadata and controls
146 lines (129 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
const webpack = require('webpack');
const express = require('express');
const browserSync = require('browser-sync').create();
const webpackDevMiddleware = require('webpack-dev-middleware');
const opn = require('better-opn');
const path = require('path');
const hasha = require('hasha');
const webpackDevServerWaitpage = require('./webpack-dev-server-waitpage');
const webpackConfig = require('../webpack.config');
const app = express();
const portfinder = require('portfinder');
const fileHashes = {};
async function serve(patternlab, configPath, buildDir = 'public') {
// @todo: move these configs + make customizable?
const root = path.resolve(__dirname, `${buildDir}`);
const preferredPort = 3000;
portfinder.basePort = preferredPort;
const webpackConfigs = await webpackConfig({
watch: true,
prod: false,
buildDir: root,
rootDir: process.cwd(),
});
const port = await portfinder
.getPortPromise()
.then((portNo) => {
return portNo;
})
.catch((err) => {
console.log(err);
return 3000;
});
// customize bs reload behavior based on the type of asset that's changed
const filesToWatch = [
{
match: [`${process.cwd()}/patternlab-config.json`],
fn: async function () {
// when the main PL config changes, clear Node's cache (so the JSON config is re-read) and trigger another PL build
// this allows config changes to show up without restarting the build!
Object.keys(require.cache).forEach(function (key) {
delete require.cache[key];
});
const config = require(configPath);
const pl = require('@pattern-lab/core')(config);
pl.build({
watch: false,
cleanPublic: true,
});
},
},
`${root}/**/*.css`,
`${root}/**/*.js`,
{
match: [`${root}/**/*.svg`, `${root}/**/*.png`, `${root}/**/*.jpg`],
fn: async function () {
browserSync.reload();
},
},
// only reload the Webpack-generated HTML files when the contents have changed
{
match: [
path.join(process.cwd(), `${root}/*.html`),
path.join(process.cwd(), `${root}/styleguide/html/*.html`),
],
fn: async function (event, filePath) {
let updatedHash = false;
const hash = await hasha.fromFile(
path.resolve(__dirname, `../${filePath}`),
{ algorithm: 'md5' }
);
if (!fileHashes[filePath] || fileHashes[filePath] !== hash) {
fileHashes[filePath] = hash;
updatedHash = true;
}
if (updatedHash && !patternlab.isBusy()) {
browserSync.reload(filePath);
}
},
},
];
browserSync.init(
{
proxy: `127.0.0.1:${port}`,
logLevel: 'info',
ui: false,
notify: false,
open: false,
tunnel: false,
port,
logFileChanges: false,
reloadOnRestart: true,
watchOptions: {
ignoreInitial: true,
},
files: filesToWatch,
},
function (err, bs) {
// assigned port from browsersync based on what's available
const assignedPort = bs.options.get('port');
opn(`http://localhost:${assignedPort}`);
const compiler = webpack(webpackConfigs);
app.use(
webpackDevServerWaitpage(compiler, {
proxyHeader: 'browsersync-proxy',
redirectPath: `http://localhost:${assignedPort}`,
})
);
app.use(
webpackDevMiddleware(compiler, {
stats: 'errors-warnings',
writeToDisk: true,
})
);
app.use(express.static(root));
app.listen(assignedPort, '127.0.0.1', function onStart(error) {
if (error) {
console.log(error);
}
});
}
);
// auto-reload the page when PL finishes compiling
patternlab.events.on('patternlab-build-end', () => {
browserSync.reload();
});
}
module.exports = {
serve,
};