Shopify / slate

Slate is a toolkit for developing Shopify themes. It's designed to assist your workflow and speed up the process of developing, testing, and deploying themes.
https://shopify.github.io/slate
MIT License
1.28k stars 364 forks source link

Using webpackChunkName breaks uploads #894

Open jaydensmith opened 5 years ago

jaydensmith commented 5 years ago

Problem

When lazy-loading using ES6 import syntax, if you use webpackChunkName liquid files no longer upload on change.

Replication steps

  1. Import a file using ES6 import and give it a webpackChunkName comment: import(/* webpackChunkName: "product" */ '../components/product')
  2. Start the server: slate start
  3. Change a liquid file, no upload is triggered.
t-kelly commented 5 years ago

I have a feeling this is more of a bug with CopyWebpackPlugin since that is what is being used to copy liquid files and trigger rebuilds when they change.

fbushell commented 5 years ago

@jaydensmith I am curious if were you able to successfully lazy-load a file on a deployed theme? I was attempting to do this in Vue but when the theme was built the lazy component didn't have a full Shopify CDN URL, only a relative path.

jaydensmith commented 5 years ago

@fbushell I did manage, it cumbersome but it works for me. I used webpack-require-from, which allowed me to include the plugin like so:

new WebpackRequireFrom({
    variableName: 'chunkPath',
    replaceSrcMethodName: 'getChunkPath'
})

Then I included the following in my theme so that the correct URLs are used, the logo is just to get the CDN URL. There may be a better way but shrug:

<script>
    window.chunkPath = 'https:{{ 'logo.svg' | asset_url | split: 'logo.svg' | first }}';
    window.getChunkPath = function (originalSrc) {
        var timeouts = {
            'chunk-collection': {{ 'chunk-collection.js' | asset_url | split: '?' | last | json }},
            'chunk-product': {{ 'chunk-product.js' | asset_url | split: '?' | last | json }}
        };

        var file = originalSrc.match(/([a-z-]+)\.js$/);

        if (file) {
            var timeout = timeouts[file[1]];
            if (timeout) {
                return originalSrc + '?' + timeout;
            }
        }

        return originalSrc;
    }
</script>

Then you can use named chunks like normal.

juanpprieto commented 4 years ago

thanks @jaydensmith Managed to get chunks working with vue dynamic imports. 🍺

In my case I also had to disable RequireFrom during dev:

slate.config.js

plugins: [
      // Assigns correct src to dynamic comp chunks
      process.env.NODE_ENV === 'production' && new WebpackRequireFrom({
        variableName: 'chunkPath',
        replaceSrcMethodName: 'getChunkPath'
      })
    ].filter(n => n)