Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: ES5 client #2658

Merged
merged 6 commits into from
Aug 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client-src/default/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ window.process = window.process || {};
window.process.env = window.process.env || {};

/* global __resourceQuery WorkerGlobalScope self */
const stripAnsi = require('strip-ansi');
const stripAnsi = require('../transpiled-modules/strip-ansi');
const socket = require('./socket');
const overlay = require('./overlay');
const { log, setLogLevel } = require('./utils/log');
Expand Down
2 changes: 1 addition & 1 deletion client-src/default/utils/log.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const log = require('webpack/lib/logging/runtime');
const log = require('../../transpiled-modules/log');

const name = 'webpack-dev-server';
// default level is set on the client side, so it does not need
Expand Down
3 changes: 3 additions & 0 deletions client-src/transpiled-modules/log.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict';

module.exports = require('webpack/lib/logging/runtime');
3 changes: 3 additions & 0 deletions client-src/transpiled-modules/strip-ansi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict';

module.exports = require('strip-ansi');
39 changes: 39 additions & 0 deletions client-src/transpiled-modules/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';

const path = require('path');
const merge = require('webpack-merge');

const base = {
mode: 'production',
output: {
path: path.resolve(__dirname, '../../client/transpiled-modules'),
libraryTarget: 'commonjs2',
},
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
},
],
},
],
},
};

module.exports = [
merge(base, {
entry: path.join(__dirname, 'log.js'),
output: {
filename: 'log.js',
},
}),
merge(base, {
entry: path.join(__dirname, 'strip-ansi.js'),
output: {
filename: 'strip-ansi.js',
},
}),
];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am afraid, some modules can use new syntax (ES 6) and we can't catch it, for example in patch version

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@evilebottnawi If that happens when we are updating a dependency, it will be caught in CI here: https://github.com/webpack/webpack-dev-server/pull/2658/files#diff-24488ac612ba9666465a7a596040ac73R43

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if we want full safety, we should do this: #2652. I don't like how that PR ended up because it has so many breaking changes in the API and seems a little risky

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sound good to me. CI is enough for me.

75 changes: 38 additions & 37 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"build:client:clients": "babel client-src/clients --out-dir client/clients",
"build:client:index": "webpack --color --config client-src/default/webpack.config.js",
"build:client:sockjs": "webpack --color --config client-src/sockjs/webpack.config.js",
"build:client:transpiled-modules": "webpack --color --config client-src/transpiled-modules/webpack.config.js",
"build:client": "rimraf ./client/* && npm-run-all -s -l -p \"build:client:**\"",
"webpack-dev-server": "node examples/run-example.js",
"release": "standard-version"
Expand Down Expand Up @@ -74,6 +75,7 @@
"@commitlint/cli": "^9.1.2",
"@commitlint/config-conventional": "^10.0.0",
"@jest/test-sequencer": "^26.3.0",
"acorn": "^8.0.1",
"babel-jest": "^26.3.0",
"babel-loader": "^8.1.0",
"body-parser": "^1.19.0",
Expand Down Expand Up @@ -107,7 +109,8 @@
"typescript": "^3.9.7",
"url-loader": "^4.1.0",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12"
"webpack-cli": "^3.3.12",
"webpack-merge": "^4.2.2"
},
"peerDependencies": {
"webpack": "^4.0.0 || ^5.0.0"
Expand Down
79 changes: 79 additions & 0 deletions test/client/bundle.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
'use strict';

const fs = require('fs');
const path = require('path');
const acorn = require('acorn');
const request = require('supertest');
const testServer = require('../helpers/test-server');
const config = require('../fixtures/simple-config/webpack.config');
const port = require('../ports-map').bundle;
const isWebpack5 = require('../helpers/isWebpack5');

describe('bundle', () => {
// the ES5 check test for the bundle will not work on webpack@5,
// because webpack@5 bundle output uses some ES6 syntax that can
// only be avoided with babel-loader
const runBundleTest = isWebpack5 ? describe.skip : describe;

runBundleTest('index.bundle.js bundled output', () => {
it('should parse with ES5', () => {
const bundleStr = fs.readFileSync(
path.resolve(__dirname, '../../client/default/index.bundle.js'),
'utf8'
);
expect(() => {
acorn.parse(bundleStr, {
ecmaVersion: 5,
});
}).not.toThrow();
});
});

runBundleTest('main.js bundled output', () => {
let server;
let req;

beforeAll((done) => {
server = testServer.start(config, { port }, done);
req = request(server.app);
});

afterAll(testServer.close);

it('should get full user bundle and parse with ES5', async () => {
const { text } = await req
.get('/main.js')
.expect('Content-Type', 'application/javascript; charset=utf-8')
.expect(200);

expect(() => {
let evalStep = 0;
acorn.parse(text, {
ecmaVersion: 5,
onToken: (token) => {
// a webpack bundle is a series of evaluated JavaScript
// strings like this: eval('...')
// if we want the bundle to work using ES5, we need to
// check that these strings are good with ES5 as well

// this can be done by waiting for tokens during the main parse
// then when we hit a string in an 'eval' function we also try
// to parse that string with ES5
if (token.type.label === 'name' && token.value === 'eval') {
evalStep += 1;
} else if (token.type.label === '(' && evalStep === 1) {
evalStep += 1;
} else if (token.type.label === 'string' && evalStep === 2) {
const program = token.value;
acorn.parse(program, {
ecmaVersion: 5,
});

evalStep = 0;
}
},
});
}).not.toThrow();
});
});
});
2 changes: 2 additions & 0 deletions test/ports-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const portsList = {
Iframe: 1,
SocketInjection: 1,
'static-publicPath-option': 1,
'contentBasePublicPath-option': 1,
bundle: 1,
};

let startPort = 8089;
Expand Down