Skip to content

Commit aa45f96

Browse files
authored
Merge pull request #453 from cidgoh/bundling_changes
Webpack bundling changes
2 parents ca25689 + 127e66e commit aa45f96

7 files changed

+100
-24
lines changed

.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module.exports = {
22
ignorePatterns: [
33
'.eslintrc.js',
44
'web/webpack.config.js',
5+
'web/webpack.schemas.js',
56
'lib/rollup.config.js',
67
'**/dist/**/*.js',
78
'.venv',

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@
2727
"lint": "prettier --check . && eslint .",
2828
"clean:lib": "rimraf lib/dist",
2929
"clean:web": "rimraf web/dist",
30+
"clean:schemas": "rimraf web/dist/dist-schemas web/dist/templates",
3031
"clean": "yarn clean:lib && yarn clean:web",
3132
"build:lib": "yarn clean:lib && rollup --config lib/rollup.config.js",
32-
"build:web": "yarn clean:web && webpack --mode=production --config web/webpack.config.js",
33+
"build:web": "yarn clean:web && webpack --mode=production --config web/webpack.config.js && yarn build:schemas",
34+
"build:schemas": "yarn clean:schemas && webpack --config web/webpack.schemas.js",
3335
"dev": "webpack serve --mode=development --config web/webpack.config.js",
3436
"test": "jest tests/"
3537
},

web/index.html

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>DataHarmonizer</title>
8+
<!--Ignore script 404 on dev server; this external import used in prod-->
9+
<script src="dist-schemas/schemas.js"></script>
810
</head>
911
<body>
1012
<div class="container-fluid">

web/index.js

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { DataHarmonizer, Footer, Toolbar } from '../lib';
2-
import menu from './templates/menu.json';
32

43
import 'bootstrap/dist/css/bootstrap.min.css';
54
import './index.css';
65

6+
import { menu, getSchema, getExportFormats } from 'schemas';
7+
78
document.addEventListener('DOMContentLoaded', function () {
89
const dhRoot = document.querySelector('#data-harmonizer-grid');
910
const dhFooterRoot = document.querySelector('#data-harmonizer-footer');
@@ -25,11 +26,7 @@ document.addEventListener('DOMContentLoaded', function () {
2526
new Toolbar(dhToolbarRoot, dh, menu, {
2627
templatePath: templatePath,
2728
releasesURL: 'https://github.com/cidgoh/pathogen-genomics-package/releases',
28-
getSchema: async (schema) => {
29-
return (await import(`./templates/${schema}/schema.json`)).default;
30-
},
31-
getExportFormats: async (schema) => {
32-
return (await import(`./templates/${schema}/export.js`)).default;
33-
},
29+
getSchema: getSchema,
30+
getExportFormats: getExportFormats,
3431
});
3532
});

web/schemas.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import menu_ from './templates/menu.json';
2+
3+
export const menu = menu_;
4+
export const getSchema = async (schema) => {
5+
return (await import(`./templates/${schema}/schema.json`)).default;
6+
};
7+
export const getExportFormats = async (schema) => {
8+
return (await import(`./templates/${schema}/export.js`)).default;
9+
};

web/webpack.config.js

+52-16
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,23 @@ module.exports = (env, argv) => {
99
output: {
1010
path: path.resolve(__dirname, 'dist'),
1111
filename: 'scripts/[name].js',
12-
assetModuleFilename: 'assets/[hash][ext][query]',
12+
},
13+
externals: {
14+
// Without declaring `schemas` as external, Webpack will attempt to look
15+
// for the `schemas` library and bundle it. However, we want our schemas
16+
// bundle to be separate from this one. This external config tells webpack
17+
// that the schemas library will instead be supplied at runtime. External
18+
// libraries can be provided in multiple ways, but we provide it through a
19+
// script reference in the HTML file outputted by this bundle.
20+
// https://webpack.js.org/configuration/externals/#externals
21+
schemas: 'schemas',
1322
},
1423
plugins: [
1524
new HtmlWebpackPlugin({
1625
template: './index.html',
1726
}),
1827
new CopyPlugin({
1928
patterns: [
20-
{
21-
context: 'templates',
22-
from: '**/*.pdf',
23-
to: 'templates/[path][name][ext]',
24-
},
25-
{
26-
context: 'templates',
27-
from: '**/schema.yaml',
28-
to: 'templates/[path][name][ext]',
29-
},
30-
{
31-
context: 'templates',
32-
from: '**/exampleInput/*',
33-
to: 'templates/[path][name][ext]',
34-
},
3529
{
3630
from: 'main.html',
3731
},
@@ -52,6 +46,12 @@ module.exports = (env, argv) => {
5246
{
5347
test: /\.(png|svg|jpg|jpeg|gif)$/i,
5448
type: 'asset/resource',
49+
generator: {
50+
// Will throw a file not found error if ``dist`` folder not in
51+
// ``{project root}/web/``.
52+
filename: '../[file]',
53+
emit: false,
54+
},
5555
},
5656
],
5757
},
@@ -61,8 +61,44 @@ module.exports = (env, argv) => {
6161
},
6262
};
6363

64+
// Difficult to run two webpack instances on a single dev server (i.e., this
65+
// file, and the other webpack file that builds schemas). So for dev servers,
66+
// we will stick to a singular build that concatenates both application and
67+
// schema content. This is fine, because the whole point of having a separate
68+
// build for schema content was to reduce production build times when users
69+
// are only editing schema files (and not the rest of the application), but
70+
// the dev server already gets around this problem through hot loading.
6471
if (argv.mode === 'development') {
6572
config.devtool = 'eval-source-map';
73+
// The external schemas lib is replaced by a direct reference to the
74+
// schemas entrypoint. When you directly reference the schemas entrypoint in
75+
// this bundle, a separate schemas library is not needed, because this
76+
// bundle will now include all schema content as well.
77+
config.resolve = {
78+
alias: {
79+
schemas: path.resolve(__dirname, 'schemas.js'),
80+
},
81+
};
82+
delete config.externals;
83+
// Need pdf SOPs that schema build previously supplied
84+
config.plugins.push(
85+
new CopyPlugin({
86+
patterns: [
87+
{
88+
context: 'templates',
89+
from: '**/*.pdf',
90+
to: 'templates/[path][name][ext]',
91+
},
92+
],
93+
})
94+
);
95+
// False emits don't play nice with dev servers either
96+
for (const rule of config.module.rules) {
97+
if (rule.hasOwnProperty('generator')) {
98+
delete rule.generator.filename;
99+
delete rule.generator.emit;
100+
}
101+
}
66102
}
67103

68104
return config;

web/webpack.schemas.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const path = require('path');
2+
const CopyPlugin = require('copy-webpack-plugin');
3+
4+
module.exports = {
5+
context: path.resolve(__dirname),
6+
entry: {
7+
schemas: './schemas.js',
8+
},
9+
output: {
10+
path: path.resolve(__dirname, 'dist', 'dist-schemas'),
11+
filename: '[name].js',
12+
globalObject: 'this',
13+
library: {
14+
name: 'schemas',
15+
type: 'umd',
16+
},
17+
},
18+
plugins: [
19+
new CopyPlugin({
20+
patterns: [
21+
{
22+
context: 'templates',
23+
from: '**/*.pdf',
24+
to: '../templates/[path][name][ext]',
25+
},
26+
],
27+
}),
28+
],
29+
};

0 commit comments

Comments
 (0)