chore(webpack): minify injected sources (#4946)

This commit is contained in:
Joel Einbinder 2021-01-08 16:15:05 -08:00 committed by GitHub
parent 135e0344fc
commit 31d980fc92
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 53 additions and 22 deletions

View file

@ -62,6 +62,7 @@
"@types/react-dom": "^17.0.0",
"@types/resize-observer-browser": "^0.1.4",
"@types/rimraf": "^3.0.0",
"@types/webpack": "^4.41.25",
"@types/ws": "7.2.6",
"@typescript-eslint/eslint-plugin": "^3.10.1",
"@typescript-eslint/parser": "^3.10.1",

View file

@ -17,10 +17,11 @@
const path = require('path');
const InlineSource = require('../../server/injected/webpack-inline-source-plugin');
/** @type {import('webpack').Configuration} */
module.exports = {
entry: path.join(__dirname, 'recorder.ts'),
devtool: 'source-map',
mode: 'development',
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
devtool: false,
module: {
rules: [
{
@ -38,6 +39,8 @@ module.exports = {
},
output: {
libraryTarget: 'var',
libraryExport: 'default',
library: 'pwExport',
filename: 'recorderSource.js',
path: path.resolve(__dirname, '../../../lib/server/injected/packed')
},

View file

@ -17,10 +17,11 @@
const path = require('path');
const InlineSource = require('../../server/injected/webpack-inline-source-plugin');
/** @type {import('webpack').Configuration} */
module.exports = {
entry: path.join(__dirname, 'consoleApi.ts'),
devtool: 'source-map',
mode: 'development',
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
devtool: false,
module: {
rules: [
{
@ -38,6 +39,8 @@ module.exports = {
},
output: {
libraryTarget: 'var',
library: 'pwExport',
libraryExport: 'default',
filename: 'consoleApiSource.js',
path: path.resolve(__dirname, '../../../lib/server/injected/packed')
},

View file

@ -82,9 +82,12 @@ export class FrameExecutionContext extends js.ExecutionContext {
for (const [name, { source }] of this.frame._page.selectors._engines)
custom.push(`{ name: '${name}', engine: (${source}) }`);
const source = `
new (${injectedScriptSource.source})([
(() => {
${injectedScriptSource.source}
return new pwExport([
${custom.join(',\n')}
])
]);
})();
`;
this._injectedScriptPromise = this._delegate.rawEvaluate(source).then(objectId => new js.JSHandle(this, 'object', objectId));
}

View file

@ -146,7 +146,11 @@ export class InjectedScript {
}
extend(source: string, params: any): any {
const constrFunction = global.eval(source);
const constrFunction = global.eval(`
(() => {
${source}
return pwExport;
})()`);
return new constrFunction(this, params);
}

View file

@ -16,11 +16,11 @@
const path = require('path');
const InlineSource = require('./webpack-inline-source-plugin.js');
/** @type {import('webpack').Configuration} */
module.exports = {
entry: path.join(__dirname, 'injectedScript.ts'),
devtool: 'source-map',
mode: 'development',
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
devtool: false,
module: {
rules: [
{
@ -38,6 +38,9 @@ module.exports = {
},
output: {
filename: 'injectedScriptSource.js',
libraryTarget: 'var',
libraryExport: 'default',
library: 'pwExport',
path: path.resolve(__dirname, '../../../lib/server/injected/packed')
},
plugins: [

View file

@ -17,10 +17,11 @@
const path = require('path');
const InlineSource = require('./webpack-inline-source-plugin.js');
/** @type {import('webpack').Configuration} */
module.exports = {
entry: path.join(__dirname, 'utilityScript.ts'),
devtool: 'source-map',
mode: 'development',
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
devtool: false,
module: {
rules: [
{
@ -38,6 +39,8 @@ module.exports = {
},
output: {
libraryTarget: 'var',
library: 'pwExport',
libraryExport: 'default',
filename: 'utilityScriptSource.js',
path: path.resolve(__dirname, '../../../lib/server/injected/packed')
},

View file

@ -22,15 +22,12 @@ module.exports = class InlineSource {
this.outFile = outFile;
}
/**
* @param {import('webpack').Compiler} compiler
*/
apply(compiler) {
compiler.hooks.emit.tapAsync('InlineSource', (compilation, callback) => {
let source = compilation.assets[path.basename(this.outFile).replace('.ts', '.js')].source();
const lastLine = source.split('\n').pop();
if (lastLine.startsWith('//# sourceMappingURL'))
source = source.substring(0, source.length - lastLine.length - 1);
if (source.endsWith(';'))
source = source.substring(0, source.length - 1);
source = '(' + source + ').default';
const source = compilation.assets[path.basename(this.outFile).replace('.ts', '.js')].source();
fs.mkdirSync(path.dirname(this.outFile), { recursive: true });
const newSource = 'export const source = ' + JSON.stringify(source) + ';';
fs.writeFileSync(this.outFile, newSource);

View file

@ -64,7 +64,11 @@ export class ExecutionContext {
utilityScript(): Promise<JSHandle<UtilityScript>> {
if (!this._utilityScriptPromise) {
const source = `new (${utilityScriptSource.source})()`;
const source = `
(() => {
${utilityScriptSource.source}
return new pwExport();
})();`;
this._utilityScriptPromise = this._delegate.rawEvaluate(source).then(objectId => new JSHandle(this, 'object', objectId));
}
return this._utilityScriptPromise;

View file

@ -554,3 +554,7 @@ it('should not use toJSON in jsonValue', async ({ page }) => {
const resultHandle = await page.evaluateHandle(() => ({ toJSON: () => 'string', data: 'data' }));
expect(await resultHandle.jsonValue()).toEqual({ data: 'data', toJSON: {} });
});
it('should not expose the injected script export', async ({ page }) => {
expect(await page.evaluate('typeof pwExport === "undefined"')).toBe(true);
});

View file

@ -40,7 +40,10 @@ function runWatch() {
const spawns = [];
for (const step of steps)
spawns.push(child_process.spawn(step.command, step.args, { stdio: 'inherit', shell: step.shell }));
spawns.push(child_process.spawn(step.command, step.args, { stdio: 'inherit', shell: step.shell, env: {
...process.env,
...step.env,
} }));
process.on('exit', () => spawns.forEach(s => s.kill()));
for (const onChange of onChanges)
runOnChanges(onChange.inputs, onChange.script);
@ -72,8 +75,11 @@ const webPackFiles = [
for (const file of webPackFiles) {
steps.push({
command: 'npx',
args: ['webpack', '--config', filePath(file), ...(watchMode ? ['--watch', '--silent', '--mode', 'development'] : [])],
args: ['webpack', '--config', filePath(file), ...(watchMode ? ['--watch', '--silent'] : [])],
shell: true,
env: {
NODE_ENV: watchMode ? 'development' : 'production'
}
});
}