Skip to content

Commit

Permalink
Merge pull request #218 from fstylermiller/master
Browse files Browse the repository at this point in the history
Refactor: lazy loading for html-wepback-plugin
  • Loading branch information
joelgallant authored Mar 7, 2023
2 parents ec4f2ca + 9fb6200 commit 82c512f
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 22 deletions.
1 change: 1 addition & 0 deletions app-config-webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@app-config/config": "^2.8.7",
"@app-config/schema": "^2.8.7",
"@app-config/utils": "^2.8.7",
"@app-config/logging": "^2.8.7",
"loader-utils": "2"
},
"peerDependencies": {
Expand Down
36 changes: 36 additions & 0 deletions app-config-webpack/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { resolve, join } from 'path';
import webpack from 'webpack';
import HtmlPlugin from 'html-webpack-plugin';
import { logger, LogLevel } from '@app-config/logging';
import AppConfigPlugin, { regex, loader, Options } from './index';

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

it('should throw an error if html-webpack-plugin is not available and headerInjection is true', () => {
process.env.APP_CONFIG = JSON.stringify({ externalApiUrl: 'https://localhost:3999' });
jest.isolateModules(async () => {
jest.mock('html-webpack-plugin', () => {
throw new Error('html-webpack-plugin not found');
});

const writeMsg = jest.fn();
logger.setWriter(writeMsg);
logger.setLevel(LogLevel.Verbose);

try {
await new Promise<void>((done, reject) => {
webpack([createOptions({ headerInjection: true })], (err, stats) => {
if (err) return reject(err);
if (!stats) return reject(new Error('no stats'));
if (stats.hasErrors()) reject(stats.toString());
done();
});
});
} catch (err) {
expect(writeMsg).toHaveBeenCalledTimes(3);
expect(writeMsg).toHaveBeenCalledWith(
'[app-config][ERROR] html-webpack-plugin not found\n',
);
expect(writeMsg).toHaveBeenCalledWith(
'[app-config][ERROR] Failed to resolve html-webpack-plugin\n',
);
expect(writeMsg).toHaveBeenCalledWith(
'[app-config][ERROR] Either include the module in your dependencies and enable the webpack plugin, or set headerInjection to false in your configuration.\n',
);
}
});
});

it('reads environment variable for app-config', async () => {
process.env.APP_CONFIG = JSON.stringify({ externalApiUrl: 'https://localhost:3999' });

Expand Down
57 changes: 35 additions & 22 deletions app-config-webpack/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { join } from 'path';
import { Compiler } from 'webpack';
import HtmlWebpackPlugin, { HtmlTagObject } from 'html-webpack-plugin';
import type { ConfigLoadingOptions, SchemaLoadingOptions } from '@app-config/main';
import type { HtmlTagObject } from 'html-webpack-plugin';
import { logger } from '@app-config/logging';

import { regex } from './loader';

Expand Down Expand Up @@ -87,28 +88,40 @@ export default class AppConfigPlugin implements Options {

injectHead(compiler: Compiler) {
compiler.hooks.compilation.tap('AppConfigPlugin', (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapPromise(
'AppConfigPlugin',
async ({ headTags, ...html }) => {
// remove placeholder <script id="app-config"></script> if it exists
const newTags: HtmlTagObject[] = headTags.filter(
({ attributes }) => attributes.id !== 'app-config',
import('html-webpack-plugin')
.then((module) => {
const HtmlWebpackPlugin = module.default;

HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapPromise(
'AppConfigPlugin',
async ({ headTags, ...html }) => {
// remove placeholder <script id="app-config"></script> if it exists
const newTags: HtmlTagObject[] = headTags.filter(
({ attributes }) => attributes.id !== 'app-config',
);

newTags.push({
tagName: 'script',
attributes: { id: 'app-config', type: 'text/javascript' },
innerHTML: ``,
voidTag: false,
meta: {},
});

return {
...html,
headTags: newTags,
};
},
);

newTags.push({
tagName: 'script',
attributes: { id: 'app-config', type: 'text/javascript' },
innerHTML: ``,
voidTag: false,
meta: {},
});

return {
...html,
headTags: newTags,
};
},
);
})
.catch((error: Error) => {
logger.error(error.message);
logger.error('Failed to resolve html-webpack-plugin');
logger.error(
'Either include the module in your dependencies and enable the webpack plugin, or set headerInjection to false in your configuration.',
);
});
});
}
}
Expand Down

0 comments on commit 82c512f

Please sign in to comment.