Skip to content

Commit 82c512f

Browse files
authored
Merge pull request #218 from fstylermiller/master
Refactor: lazy loading for html-wepback-plugin
2 parents ec4f2ca + 9fb6200 commit 82c512f

File tree

3 files changed

+72
-22
lines changed

3 files changed

+72
-22
lines changed

app-config-webpack/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"@app-config/config": "^2.8.7",
3535
"@app-config/schema": "^2.8.7",
3636
"@app-config/utils": "^2.8.7",
37+
"@app-config/logging": "^2.8.7",
3738
"loader-utils": "2"
3839
},
3940
"peerDependencies": {

app-config-webpack/src/index.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { resolve, join } from 'path';
22
import webpack from 'webpack';
33
import HtmlPlugin from 'html-webpack-plugin';
4+
import { logger, LogLevel } from '@app-config/logging';
45
import AppConfigPlugin, { regex, loader, Options } from './index';
56

67
const examplesDir = resolve(__dirname, '../../examples');
@@ -47,6 +48,41 @@ describe('frontend-webpack-project example', () => {
4748
});
4849
});
4950

51+
it('should throw an error if html-webpack-plugin is not available and headerInjection is true', () => {
52+
process.env.APP_CONFIG = JSON.stringify({ externalApiUrl: 'https://localhost:3999' });
53+
jest.isolateModules(async () => {
54+
jest.mock('html-webpack-plugin', () => {
55+
throw new Error('html-webpack-plugin not found');
56+
});
57+
58+
const writeMsg = jest.fn();
59+
logger.setWriter(writeMsg);
60+
logger.setLevel(LogLevel.Verbose);
61+
62+
try {
63+
await new Promise<void>((done, reject) => {
64+
webpack([createOptions({ headerInjection: true })], (err, stats) => {
65+
if (err) return reject(err);
66+
if (!stats) return reject(new Error('no stats'));
67+
if (stats.hasErrors()) reject(stats.toString());
68+
done();
69+
});
70+
});
71+
} catch (err) {
72+
expect(writeMsg).toHaveBeenCalledTimes(3);
73+
expect(writeMsg).toHaveBeenCalledWith(
74+
'[app-config][ERROR] html-webpack-plugin not found\n',
75+
);
76+
expect(writeMsg).toHaveBeenCalledWith(
77+
'[app-config][ERROR] Failed to resolve html-webpack-plugin\n',
78+
);
79+
expect(writeMsg).toHaveBeenCalledWith(
80+
'[app-config][ERROR] Either include the module in your dependencies and enable the webpack plugin, or set headerInjection to false in your configuration.\n',
81+
);
82+
}
83+
});
84+
});
85+
5086
it('reads environment variable for app-config', async () => {
5187
process.env.APP_CONFIG = JSON.stringify({ externalApiUrl: 'https://localhost:3999' });
5288

app-config-webpack/src/index.ts

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { join } from 'path';
22
import { Compiler } from 'webpack';
3-
import HtmlWebpackPlugin, { HtmlTagObject } from 'html-webpack-plugin';
43
import type { ConfigLoadingOptions, SchemaLoadingOptions } from '@app-config/main';
4+
import type { HtmlTagObject } from 'html-webpack-plugin';
5+
import { logger } from '@app-config/logging';
56

67
import { regex } from './loader';
78

@@ -87,28 +88,40 @@ export default class AppConfigPlugin implements Options {
8788

8889
injectHead(compiler: Compiler) {
8990
compiler.hooks.compilation.tap('AppConfigPlugin', (compilation) => {
90-
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapPromise(
91-
'AppConfigPlugin',
92-
async ({ headTags, ...html }) => {
93-
// remove placeholder <script id="app-config"></script> if it exists
94-
const newTags: HtmlTagObject[] = headTags.filter(
95-
({ attributes }) => attributes.id !== 'app-config',
91+
import('html-webpack-plugin')
92+
.then((module) => {
93+
const HtmlWebpackPlugin = module.default;
94+
95+
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapPromise(
96+
'AppConfigPlugin',
97+
async ({ headTags, ...html }) => {
98+
// remove placeholder <script id="app-config"></script> if it exists
99+
const newTags: HtmlTagObject[] = headTags.filter(
100+
({ attributes }) => attributes.id !== 'app-config',
101+
);
102+
103+
newTags.push({
104+
tagName: 'script',
105+
attributes: { id: 'app-config', type: 'text/javascript' },
106+
innerHTML: ``,
107+
voidTag: false,
108+
meta: {},
109+
});
110+
111+
return {
112+
...html,
113+
headTags: newTags,
114+
};
115+
},
96116
);
97-
98-
newTags.push({
99-
tagName: 'script',
100-
attributes: { id: 'app-config', type: 'text/javascript' },
101-
innerHTML: ``,
102-
voidTag: false,
103-
meta: {},
104-
});
105-
106-
return {
107-
...html,
108-
headTags: newTags,
109-
};
110-
},
111-
);
117+
})
118+
.catch((error: Error) => {
119+
logger.error(error.message);
120+
logger.error('Failed to resolve html-webpack-plugin');
121+
logger.error(
122+
'Either include the module in your dependencies and enable the webpack plugin, or set headerInjection to false in your configuration.',
123+
);
124+
});
112125
});
113126
}
114127
}

0 commit comments

Comments
 (0)