lasso-js / lasso

Advanced JavaScript module bundler, asset pipeline and optimizer
582 stars 75 forks source link

Append params to resources #206

Closed design-media closed 7 years ago

design-media commented 7 years ago

Similar to urlPrefix, there should be a config to append a string to each resource.

For example, add to each resource (CSS, JS), a GET parameter when requesting the resource: <link rel="stylesheet" href="%CDN_URL%/static/page.css?%PARAM%=%VALUE%"> ... <script src="%CDN_URL%/static/page.js?%PARAM%=%VALUE%"></script>

design-media commented 7 years ago

This feature will be very useful for cache busting, versioning, data center selection, etc.

design-media commented 7 years ago

Maybe extend "Custom attributes for Script & Style tags"? Even-though it should be an option in the lasso config JSON.

patrick-steele-idem commented 7 years ago

It might not be the most straightforward solution, but you can use a custom writer to have full control over how the URL is generated for bundle. Please see the following issue for details: https://github.com/lasso-js/lasso/issues/90

Will that work for you?

design-media commented 7 years ago

We'll check https://github.com/lasso-js/lasso/issues/90 and https://gist.github.com/StarpTech/e77e495b0c21a64f811a9c90f004001a

The only thing is that as we'll override the Writer and on each Lasso update we'll have to merge the changes.

Isn't there an easier way, like to make/extend lasso-marko?

patrick-steele-idem commented 7 years ago

After refreshing my memory of the code, it looks like you can register a custom Lasso plugin to modify the URL for both resources and bundles that are written using the bundleWritten and resourceWritten hooks:

module.exports = function myUrlModificationPlugin(lasso, config) {
    lasso.on('beforeBuildPage', (event) => {
        var context = event.context;

        context.on('bundleWritten', (event) => {
            var bundle = event.bundle;
            bundle.url += '?foo=bar';
        });

        context.on('resourceWritten', (event) => {
            event.url += '?foo=bar';
        });
    });
};

I hope that solution works for you. If you still have questions please let me know.

patrick-steele-idem commented 7 years ago

As a side note, I don't think we have tests for the bundleWritten and the resourceWritten hooks. If someone has time to add tests that would be greatly appreciated. All you need to do is duplicate the following test directory and modify it to test for the bundleWritten and the resourceWritten hooks: lasso/test/autotests/plugins/events/

design-media commented 7 years ago

@patrick-steele-idem Thanks for the solution!

Also, we'll try to contribute with the tests.

design-media commented 7 years ago

I've just tried your suggestion and, unfortunately, it doesn't work. The 2 events are never triggered.

Tried adding context.on('beforeAddDependencyToAsyncPageBundle') and that worked. Are the bundleWritten and resourceWritten events emitted on the context scope?

austinkelleher commented 7 years ago

It looks like bundleWritten is only emitted by the Writer here. It is not emitted by the lassoContext.

austinkelleher commented 7 years ago

Maybe we should make the lassoContext emit bundleWritten. What do you think @patrick-steele-idem?

patrick-steele-idem commented 7 years ago

Good catch @austinkelleher. I'm not seeing a reason to not also emit it on lassoContext. Anyone interested in making that change and adding tests?

austinkelleher commented 7 years ago

I'll go ahead and make these changes.

design-media commented 7 years ago

I've just made a small change in the writer.js, when triggering bundleWritten on the Writer, to also emit it on lassoContext.

_this.emit('bundleWritten', { bundle: bundle }); lassoContext.emit('bundleWritten', { bundle: bundle });

But at the moment when the event is triggered, bundle.url is undefined.