Skip to content

feat(rollup): provide sourcemaps for all output types #641

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

Merged
merged 1 commit into from
Apr 15, 2019

Conversation

jbedard
Copy link
Collaborator

@jbedard jbedard commented Mar 31, 2019

This adds sourcemap targets output groups for all the output formats.

Today there's the default target which outputs the es5 bundle.js and bundle.js.map. Then there's sub-targets such as .es2015.js, .umd.js etc. There's also .js which is the same as the default target but without the .map. But there's no way to easily fetch the .js+map of only the es2015 bundle.

This adds a .js.map target alongside every .js target.
This adds an output-group for each bundle type. The tests show an example of filegroups consuming these output-groups.

template = ctx.file._no_explore_html,
substitutions = {},
)
# There is no source map or explorer output when code-splitting but we still need to satisfy the output
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Seems like there's no source maps when code-splitting today? I guess that could be a future task...

Copy link
Collaborator

Choose a reason for hiding this comment

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

what does the rollup program produce? I bet it still creates sourcemaps, and having a size explorer for chunks is a pretty critical feature, could fix this next

run_terser(ctx, ctx.outputs.build_es5, ctx.outputs.build_es5_min_debug, debug = True)
source_map_min = run_terser(ctx, ctx.outputs.build_es5, ctx.outputs.build_es5_min)
run_terser(ctx, ctx.outputs.build_es5, ctx.outputs.build_es5_min_debug, debug = True, in_source_map = source_map_min)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I guess we could just copy the source_map_min to ctx.outputs.build_es5_map just so the build_es5_map target exists for consistency?

Copy link
Collaborator

Choose a reason for hiding this comment

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

But it would have the wrong content, wouldn't it? I think we could just fix #175 next

run_sourcemapexplorer(ctx, ctx.outputs.build_es5_min, source_map, ctx.outputs.explore_html)
files = [ctx.outputs.build_es5_min, source_map]

# TODO: ?
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Is this worth doing for every sourcemap?

Copy link
Collaborator

Choose a reason for hiding this comment

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

The user needs to be able to reason about what makes their bundle large under different cases. If two flavors of JS output could have different size characteristics, then the user would have to be able to debug them separately. But we shouldn't expose more of these sourcemapexplorer things than necessary.

Also I feel like we have gone too far with including lots of behaviors in this rule. Maybe sourcemapexplorer should be a separate rule, WDYT?

@jbedard jbedard force-pushed the source-maps branch 2 times, most recently from 1e9086a to e27f62f Compare April 1, 2019 05:08
@@ -0,0 +1 @@
{"version":3,"file":"bundle.cjs.js.map","sources":["bundle.es6/internal/e2e/rollup/fum/index.js","../../../../../../../../../../../execroot/build_bazel_rules_nodejs/bazel-out/__platform__-fastbuild/bin/internal/e2e/rollup/bundle.es6/external/npm/node_modules/hello/index.js","bundle.es6/internal/e2e/rollup/bar.js","bundle.es6/internal/e2e/rollup/foo.js"],"sourcesContent":["export const fum = 'Wonderland';\n","export default 'Hello';\n","export const name = 'Alice';\n","import {fum} from 'fumlib';\nimport hello from 'hello';\nimport {thing} from 'some_global_var';\n\nimport {name} from './bar';\n\nconsole.log(`${hello}, ${name} in ${fum}`);\n\n// Tests for @PURE annotations\n/*@__PURE__*/\nconsole.log('side-effect');\n\nclass Impure {\n constructor() {\n console.log('side-effect')\n }\n}\n\n/*@__PURE__*/new Impure();\n\n// Test for sequences = false\nexport class A {\n a() {\n return document.a;\n }\n}\nfunction inline_me() {\n return 'abc';\n}\nconsole.error(new A().a(), inline_me(), thing);\n"],"names":["thing"],"mappings":";;;;;;;;;;;AAAO,MAAM,GAAG,GAAG,YAAY,CAAC;;ACAhC,YAAe,OAAO,CAAC;;ACAhB,MAAM,IAAI,GAAG,OAAO,CAAC;;ACM5B,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAC3C,AAYA;;AAEA,AAAO,MAAM,CAAC,CAAC;EACb,CAAC,GAAG;IACF,OAAO,QAAQ,CAAC,CAAC,CAAC;GACnB;CACF;AACD,SAAS,SAAS,GAAG;EACnB,OAAO,KAAK,CAAC;CACd;AACD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,EAAEA,qBAAK,CAAC,CAAC;;;;"}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm questioning the volume of golden content here. Do we really want to assert on the content of all the sourcemaps? If you just want to assert that the rollup_bundle rule has some output file, we can do that just by referencing it as an input to any rule (like a trivial genrule)

run_terser(ctx, ctx.outputs.build_es5, ctx.outputs.build_es5_min_debug, debug = True)
source_map_min = run_terser(ctx, ctx.outputs.build_es5, ctx.outputs.build_es5_min)
run_terser(ctx, ctx.outputs.build_es5, ctx.outputs.build_es5_min_debug, debug = True, in_source_map = source_map_min)

Copy link
Collaborator

Choose a reason for hiding this comment

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

But it would have the wrong content, wouldn't it? I think we could just fix #175 next

run_sourcemapexplorer(ctx, ctx.outputs.build_es5_min, source_map, ctx.outputs.explore_html)
files = [ctx.outputs.build_es5_min, source_map]

# TODO: ?
Copy link
Collaborator

Choose a reason for hiding this comment

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

The user needs to be able to reason about what makes their bundle large under different cases. If two flavors of JS output could have different size characteristics, then the user would have to be able to debug them separately. But we shouldn't expose more of these sourcemapexplorer things than necessary.

Also I feel like we have gone too far with including lots of behaviors in this rule. Maybe sourcemapexplorer should be a separate rule, WDYT?

@@ -664,13 +690,22 @@ ROLLUP_ATTRS = {

ROLLUP_OUTPUTS = {
"build_cjs": "%{name}.cjs.js",
"build_cjs_map": "%{name}.cjs.js.map",
Copy link
Collaborator

Choose a reason for hiding this comment

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

this needs some re-organization as a starlark provider so the JS and .map can stay together as tuple through the dependent build steps...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

👍

Would we still want the targets for individual files? Only the .js ones which exist today?

Copy link
Collaborator Author

@jbedard jbedard Apr 7, 2019

Choose a reason for hiding this comment

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

I got this working locally, but does this mean people must use the --output_groups flag instead of something similar to the bundle.es2015.js used today?

Note that I dropped the ROLLUP_OUTPUTS and only used declare_file, DefaultInfo and OutputGroupInfo

Copy link
Collaborator

@alexeagle alexeagle left a comment

Choose a reason for hiding this comment

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

I think OutputGroup may be the wrong thing - it seems that it makes it impossible for a downstream rule to request a particular output? Like https://github.com/angular/angular-bazel-example/blob/master/src/BUILD.bazel#L179

.replace(/\\r\\n/g, '\\n');
.replace(/\\r\\n/g, '\\n')
// Replace platform specific directories in paths
.replace(/\/\w+-fastbuild\//g, '/__platform__-fastbuild/')
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this related? could be a separate PR?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was getting different folder names outputted here compared to circleci. Were the golden files previously generated by circleci so they have the circleci platform? I figured this was better then me manually editing the golden files...

@kyliau
Copy link
Collaborator

kyliau commented Apr 8, 2019

I think OutputGroup may be the wrong thing - it seems that it makes it impossible for a downstream rule to request a particular output? Like https://github.com/angular/angular-bazel-example/blob/master/src/BUILD.bazel#L179

If ROLLUP_OUTPUTS is restored then downstream targets could continue to request a specific output as before.

I think OutputGroup could still be useful, because it provides logical grouping of the outputs.
The downside is that downstream targets would need to declare an intermediate filegroup in order to retrieve the sourcemap.

rollup_bundle(
    name = "bundle",
    entry_point = "src/main.prod",
    deps = [
        // ...
    ],
)

filegroup(
    name = "bundle_es2015_min_with_sourcemap"
    srcs = [":bundle"],
    output_group = "es2015_min",
)

web_package(
    name = "prodapp",
    assets = _ASSETS + [
        ":bundle.min.js",
        ":bundle.min.es2015.js",
    ],
    data = [
        ":bundle_es2015_min_with_sourcemap",
    ],
    index_html = "index.html",
)

@jbedard
Copy link
Collaborator Author

jbedard commented Apr 9, 2019

I've added a commit changing rollup_bundle to a macro which runs rollup as well as declaring a bunch of filegroup targets for a) each bundle type .js and .map b) just the .js file.

I think this is working, but I'm not sure if the macro+filegroups is the best solution, and haven't fully tested it. @alexeagle I'm not sure what you meant by "starlark provider", is that another way of doing this?

@jbedard jbedard force-pushed the source-maps branch 6 times, most recently from 3c0819f to b1cf64c Compare April 13, 2019 01:59
@jbedard
Copy link
Collaborator Author

jbedard commented Apr 13, 2019

Update to just add an OutputGroupInfo to the result, with one group per bundle type. Without specifically consuming these new output-groups no one should notice this change.

Since this PR is now just this small output-group addition I've greatly simplified the diff and removed anything unnecessary.

Instead of adding new tests I've just executed the existing tests (a second time), but using the output-group instead of default info.


jasmine_node_test(
name = "test-outputgroups",
srcs = glob(["*.spec.js"]),
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should probably be another spec file that asserts the existence of sourcemap for each flavor in addition to the js file. Existing rollup.spec.js only checks sourcemap for the default output.

@jbedard
Copy link
Collaborator Author

jbedard commented Apr 14, 2019

I've changed the tests to assert the presence of the .map files alongside .js when using the output groups.

Copy link
Collaborator

@kyliau kyliau left a comment

Choose a reason for hiding this comment

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

LGTM. Could you please take a look at the test failure on CI? The test failed on Windows, so probably it's just a path issue in the spec.

@kyliau kyliau merged commit 354c25a into bazel-contrib:master Apr 15, 2019
@kyliau
Copy link
Collaborator

kyliau commented Apr 15, 2019

Output groups could be requested on the command line.
For example,

bazel build :bundle --output_groups=es2015_min

See https://docs.bazel.build/versions/master/command-line-reference.html#flag--output_groups

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants