Skip to content

Commit 9455511

Browse files
authored
feat: webpack 5 support (#3)
1 parent 7bd0695 commit 9455511

File tree

9 files changed

+183
-138
lines changed

9 files changed

+183
-138
lines changed

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@
7979
"microbundle": "^0.12.4",
8080
"preact": "^10.5.7",
8181
"sucrase": "^3.16.0",
82-
"terser-webpack-plugin": "^1.4.5",
83-
"ts-loader": "^6.2.2",
84-
"webpack": "^4.44.2"
82+
"ts-loader": "^9.2.6",
83+
"webpack": "^5.65.0",
84+
"webpack-4": "./test/webpacks/4"
8585
},
8686
"dependencies": {
8787
"@babel/core": "^7.12.7",
@@ -94,8 +94,8 @@
9494
"magic-string": "^0.25.7",
9595
"regenerator-runtime": "^0.13.7",
9696
"rollup": "^1.32.1",
97-
"terser": "^4.8.0",
98-
"webpack-sources": "^1.4.3"
97+
"terser": "^5.10.0",
98+
"webpack-sources": "^3.2.2"
9999
},
100100
"peerDependencies": {
101101
"@babel/preset-env": ">= 7.10",

src/index.js

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import util from 'util';
1818
import { gzip } from 'zlib';
1919
import { promises as fs } from 'fs';
20-
import * as webpack from 'webpack';
20+
import * as defaultWebpack from 'webpack';
2121
import { SourceMapSource, RawSource } from 'webpack-sources';
2222
import { rollup } from 'rollup';
2323
import commonjsPlugin from '@rollup/plugin-commonjs';
@@ -75,7 +75,8 @@ export default class OptimizePlugin {
7575
/**
7676
* @param {Partial<DEFAULT_OPTIONS>?} [options]
7777
*/
78-
constructor (options) {
78+
constructor (options, webpack = defaultWebpack) {
79+
this.webpack = webpack;
7980
this.options = Object.assign({}, options || {});
8081
for (const i in DEFAULT_OPTIONS) {
8182
if (this.options[i] == null) this.options[i] = DEFAULT_OPTIONS[i];
@@ -104,14 +105,18 @@ export default class OptimizePlugin {
104105
}
105106

106107
isWebpack4 () {
107-
return webpack.version[0] === '4';
108+
return this.webpack.version[0] === '4';
109+
}
110+
111+
isWebpack5 () {
112+
return this.webpack.version[0] === '5';
108113
}
109114

110115
serializeOptions () {
111116
return this._serialized || (this._serialized = JSON.stringify(this.options));
112117
}
113118

114-
async optimize (compiler, compilation, chunks) {
119+
async optimize (compiler, compilation, chunkFiles) {
115120
const cwd = compiler.context;
116121
const { timings, start, end } = createPerformanceTimings();
117122

@@ -124,10 +129,6 @@ export default class OptimizePlugin {
124129
};
125130

126131
const processing = new WeakMap();
127-
const chunkFiles = Array.from(chunks).reduce(
128-
(acc, chunk) => acc.concat(Array.from(chunk.files || [])),
129-
[]
130-
);
131132
const chunkAssets = Array.from(compilation.additionalChunkAssets || []);
132133
const files = [...chunkFiles, ...chunkAssets];
133134

@@ -150,7 +151,7 @@ export default class OptimizePlugin {
150151
const original = { file, source, map, options };
151152
// @ts-ignore-next
152153
const result = this.workerPool.enqueue(original);
153-
pending = result.then(this.buildResultSources.bind(this, original));
154+
pending = result.then(this.buildResultSources.bind(this, original)).catch(console.error);
154155
processing.set(asset, pending);
155156

156157
const t = ` └ ${file}`;
@@ -449,14 +450,33 @@ export default class OptimizePlugin {
449450
compilation.chunkTemplate.hooks.hashForChunk.tap(NAME, updateWithHash.bind(null, null));
450451
} else {
451452
// @ts-ignore
452-
webpack.javascript.JavascriptModulesPlugin.getCompilationHooks(compilation).chunkHash.tap(NAME, updateWithHash);
453+
this.webpack.javascript.JavascriptModulesPlugin.getCompilationHooks(compilation).chunkHash.tap(NAME, updateWithHash);
453454
}
454455
}
455456

456457
apply (compiler) {
457458
compiler.hooks.compilation.tap(NAME, compilation => {
458459
this.updateChunkHash(compilation);
459-
compilation.hooks.optimizeChunkAssets.tapPromise(NAME, this.optimize.bind(this, compiler, compilation));
460+
461+
if (this.isWebpack5()) {
462+
compilation.hooks.processAssets.tapPromise({
463+
name: NAME,
464+
stage: this.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE
465+
}, (assets) => {
466+
const chunkFiles = Object.keys(assets);
467+
468+
return this.optimize(compiler, compilation, chunkFiles);
469+
});
470+
} else {
471+
compilation.hooks.optimizeChunkAssets.tapPromise(NAME, (chunks) => {
472+
const chunkFiles = Array.from(chunks).reduce(
473+
(acc, chunk) => acc.concat(Array.from(chunk.files || [])),
474+
[]
475+
);
476+
477+
return this.optimize(compiler, compilation, chunkFiles);
478+
});
479+
}
460480
});
461481
}
462482
}

src/lib/rollup-plugin-terser-simple.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import { toBabelMap } from './util';
2020
export default function rollupPluginTerserSimple () {
2121
return {
2222
name: 'rollup-plugin-terser-simple',
23-
renderChunk (source, chunk, options) {
24-
const { code, map } = terser.minify(source, {
23+
async renderChunk (source, chunk, options) {
24+
const { code, map } = await terser.minify(source, {
2525
compress: {
2626
global_defs: {
2727
'typeof self': '"object"',

src/worker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export async function process ({ file, source, map, options = {} }) {
9292

9393
if (minify) {
9494
start('modern-minify');
95-
const minified = terser.minify(modern.code, {
95+
const minified = await terser.minify(modern.code, {
9696
// Enables shorthand properties in objects and object patterns:
9797
ecma: 2017,
9898
module: false,

test/_util.js

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
* the License.
1515
*/
1616

17+
import { promises as fs } from 'fs';
1718
import path from 'path';
1819
import { gzip as gzipSync } from 'zlib';
1920
import util from 'util';
20-
import webpack from 'webpack';
2121
import CleanPlugin from 'clean-webpack-plugin';
22-
// import TerserPlugin from 'terser-webpack-plugin';
2322

2423
export function sleep (ms) {
2524
return new Promise(resolve => setTimeout(resolve, ms));
@@ -58,7 +57,7 @@ export async function printSizes (assets, name, console) {
5857
console.log(str);
5958
}
6059

61-
export function runWebpack (fixture, { output = {}, plugins = [], module = {}, resolve = {}, ...config } = {}, console) {
60+
export function runWebpack (webpack, fixture, { output = {}, plugins = [], module = {}, resolve = {}, ...config } = {}, console) {
6261
return run(callback => webpack({
6362
mode: 'production',
6463
devtool: false,
@@ -83,7 +82,7 @@ export function runWebpack (fixture, { output = {}, plugins = [], module = {}, r
8382
}, callback), console);
8483
}
8584

86-
export function watchWebpack (fixture, { output, plugins, context, ...config } = {}, console) {
85+
export function watchWebpack (webpack, fixture, { output, plugins, context, ...config } = {}, console) {
8786
context = context || path.resolve(__dirname, 'fixtures', fixture);
8887
const compiler = webpack({
8988
mode: 'production',
@@ -100,20 +99,27 @@ export function watchWebpack (fixture, { output, plugins, context, ...config } =
10099
return compiler;
101100
}
102101

103-
export function statsWithAssets (stats) {
104-
stats.assets = Object.keys(stats.compilation.assets).reduce((acc, name) => {
105-
acc[name] = stats.compilation.assets[name].source();
106-
return acc;
107-
}, {});
108-
return stats;
102+
export async function statsWithAssets (stats) {
103+
const assets = Object.keys(stats.compilation.assets);
104+
const basePath = stats.compilation.outputOptions.path;
105+
const contents = {};
106+
107+
await Promise.all(assets.map(async (asset) => {
108+
const assetPath = path.join(basePath, asset);
109+
const content = await fs.readFile(assetPath, 'utf8');
110+
111+
contents[asset] = content;
112+
}));
113+
114+
stats.assets = contents;
109115
}
110116

111117
function run (runner, console) {
112118
return new Promise((resolve, reject) => {
113-
runner((err, stats) => {
119+
runner(async (err, stats) => {
114120
if (err) return reject(err);
115121

116-
statsWithAssets(stats);
122+
await statsWithAssets(stats);
117123

118124
stats.info = stats.toJson({ assets: true, chunks: true });
119125

test/_webpacks.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export const webpacks = [
2+
[5, require('webpack'), require.resolve('ts-loader')],
3+
[4, require('webpack-4/node_modules/webpack'), require.resolve('webpack-4/node_modules/ts-loader')]
4+
];

test/fixtures/basic/entry.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@
1515
*/
1616

1717
console.log('hello world');
18+
19+
Object.defineProperty(window, 'test', {
20+
value: 'hello world'
21+
});

0 commit comments

Comments
 (0)