Skip to content

Commit

Permalink
new: Move InlineManifestPlugin into the project. (#33)
Browse files Browse the repository at this point in the history
* Start on new plugin.

* Add tests.

* Fix tests.
  • Loading branch information
milesj authored Apr 1, 2020
1 parent 7a0c7a8 commit 0cb6839
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ logs/
# Directories
node_modules/
lib/
public/

# Configs
.babelrc
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"setup": "tsc --build && beemo create-config eslint prettier",
"build": "beemo typescript --build --reference-workspaces",
"clean": "rm -rf packages/*/{lib,*.tsbuildinfo}",
"test": "yarn run build && yarn run jest && yarn run lint",
"test": "yarn run build && yarn run jest && yarn run lint && yarn run test:webpack",
"test:webpack": "NODE_ENV=production webpack --config ./packages/config-webpack/tests/webpack.test.config.js",
"lint": "beemo eslint .",
"jest": "beemo jest",
"prettier": "beemo prettier",
Expand All @@ -29,7 +30,8 @@
"eslint",
"jest",
"prettier",
"typescript"
"typescript",
"webpack"
],
"settings": {
"node": true
Expand Down
1 change: 0 additions & 1 deletion packages/config-webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
"fast-glob": "^3.2.2",
"file-loader": "^6.0.0",
"html-webpack-plugin": "^4.0.1",
"inline-manifest-webpack-plugin": "^4.0.2",
"is-docker": "^2.0.0",
"terser-webpack-plugin": "^2.3.5",
"url-loader": "^4.0.0",
Expand Down
12 changes: 8 additions & 4 deletions packages/config-webpack/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import path from 'path';
import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import InlineManifestWebpackPlugin from 'inline-manifest-webpack-plugin';
import TerserPlugin from 'terser-webpack-plugin';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import { WebpackConfig } from '@beemo/driver-webpack';
Expand All @@ -14,6 +13,7 @@ import {
GQL_EXT_PATTERN,
TJSX_EXT_PATTERN,
} from '@airbnb/nimbus-common';
import InlineManifestPlugin from './plugins/InlineManifestPlugin';
import { PORT, ROOT, PROD, getESMAliases, getFavIcon, getParallelValue } from './helpers';

export interface WebpackOptions {
Expand All @@ -22,6 +22,7 @@ export interface WebpackOptions {
parallel?: boolean | string | number;
port?: string | number;
react?: boolean;
root?: string;
sourceMaps?: boolean;
srcFolder: string;
}
Expand All @@ -32,11 +33,12 @@ export function getConfig({
parallel = true,
port = PORT,
react = false,
root = ROOT,
sourceMaps = false,
srcFolder,
}: WebpackOptions): WebpackConfig {
const srcPath = path.join(ROOT, srcFolder);
const publicPath = path.join(ROOT, buildFolder);
const srcPath = path.join(root, srcFolder);
const publicPath = path.join(root, buildFolder);
const entry = [srcPath];
const plugins = [
new webpack.NamedChunksPlugin(),
Expand Down Expand Up @@ -65,7 +67,7 @@ export function getConfig({
if (PROD) {
plugins.push(
// Inline the runtime chunk to enable long-term caching
new InlineManifestWebpackPlugin(),
new InlineManifestPlugin(),
);
} else if (react) {
plugins.push(
Expand All @@ -79,6 +81,8 @@ export function getConfig({

bail: PROD,

context: root,

entry: {
core: entry,
},
Expand Down
97 changes: 97 additions & 0 deletions packages/config-webpack/src/plugins/InlineManifestPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* eslint-disable no-param-reassign, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, import/no-extraneous-dependencies */

import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import sourceMappingURL from 'source-map-url';

function getAssetName(chunks: webpack.compilation.Chunk[], chunkName: string) {
return chunks.filter((chunk) => chunk.name === chunkName)?.[0]?.files[0];
}

function inlineWhenMatched(
compilation: webpack.compilation.Compilation,
scripts: HtmlWebpackPlugin.HtmlTagObject[],
manifestAssetName: string,
) {
return scripts.map((script) => {
const isManifestScript =
script.tagName === 'script' &&
typeof script.attributes.src === 'string' &&
script.attributes.src?.includes(manifestAssetName);

if (isManifestScript) {
return {
tagName: 'script',
voidTag: true,
attributes: {
type: 'text/javascript',
},
innerHTML: sourceMappingURL.removeFrom(compilation.assets[manifestAssetName].source()),
};
}

return script;
});
}

export default class InlineManifestPlugin implements webpack.Plugin {
name: string;

constructor(name: string = 'runtime') {
this.name = name;
}

apply(compiler: webpack.Compiler) {
const { name } = this;

compiler.hooks.emit.tap('InlineManifestWebpackPlugin', (compilation) => {
const assetName = getAssetName(compilation.chunks, name);

if (assetName) {
delete compilation.assets[assetName];
}
});

compiler.hooks.compilation.tap('InlineManifestWebpackPlugin', (compilation) => {
const hooks = HtmlWebpackPlugin.getHooks(compilation);

hooks.alterAssetTags.tapAsync('InlineManifestWebpackPlugin', (data, cb) => {
const assetName = getAssetName(compilation.chunks, name);

if (assetName) {
data.assetTags.scripts = inlineWhenMatched(
compilation,
data.assetTags.scripts,
assetName,
);
}

cb(null, data);
});

hooks.beforeAssetTagGeneration.tapAsync(
'InlineManifestWebpackPlugin',
(htmlPluginData, cb) => {
const assetName = getAssetName(compilation.chunks, name);

// @ts-ignore Option exists
if (assetName && htmlPluginData.plugin.options.inject === false) {
const { assets } = htmlPluginData;
const runtime = `<script>${sourceMappingURL.removeFrom(
compilation.assets[assetName].source(),
)}</script>`;
const runtimeIndex = assets.js.indexOf(assets.publicPath + assetName);

if (runtimeIndex >= 0) {
assets.js.splice(runtimeIndex, 1);
}

assets.js.push(runtime);
}

cb(null, htmlPluginData);
},
);
});
}
}
11 changes: 11 additions & 0 deletions packages/config-webpack/tests/src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<title>Test</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<div id="root"></div>
</body>
</html>
2 changes: 2 additions & 0 deletions packages/config-webpack/tests/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line no-console
console.log('Webpack build test!');
6 changes: 6 additions & 0 deletions packages/config-webpack/tests/webpack.test.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const { getConfig } = require('../lib');

module.exports = getConfig({
root: __dirname,
srcFolder: 'src',
});
5 changes: 0 additions & 5 deletions types/inline-manifest-webpack-plugin.d.ts

This file was deleted.

8 changes: 8 additions & 0 deletions types/source-map-url.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare module 'source-map-url' {
class SMU {
removeFrom(code: string): string;
}

const smu: SMU;
export default smu;
}
9 changes: 1 addition & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6797,13 +6797,6 @@ init-package-json@^1.10.3:
validate-npm-package-license "^3.0.1"
validate-npm-package-name "^3.0.0"

inline-manifest-webpack-plugin@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/inline-manifest-webpack-plugin/-/inline-manifest-webpack-plugin-4.0.2.tgz#39bf4144c3a6210686bfe44c73f2c883681e51bb"
integrity sha512-j1Q0Y7m2GVsTxnOzQ7YzIlfn5Th2Ga6Ivoqme1G0iGZc8m7R3aQY8HfzLW7ew3CwmqdZb/O26mf9Ak2JA7zzKg==
dependencies:
source-map-url "0.4.0"

inquirer@^6.2.0:
version "6.5.1"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.1.tgz#8bfb7a5ac02dac6ff641ac4c5ff17da112fcdb42"
Expand Down Expand Up @@ -10940,7 +10933,7 @@ source-map-support@^0.5.0, source-map-support@^0.5.6, source-map-support@~0.5.12
buffer-from "^1.0.0"
source-map "^0.6.0"

source-map-url@0.4.0, source-map-url@^0.4.0:
source-map-url@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
Expand Down

0 comments on commit 0cb6839

Please sign in to comment.