sveltejs / svelte-loader

Webpack loader for svelte components.
MIT License
597 stars 72 forks source link

Support Webpack 5, drop copypasted webpack-virtual-modules #151

Closed non25 closed 3 years ago

non25 commented 3 years ago

It drops webpack-virtual-modules in favor of much more simple and sane setup described here: https://github.com/webpack/webpack/issues/11074#issuecomment-648658214

The setup works both for webpack 4 and 5. Emitted css reloads just fine on component change on both of them.

This PR changes make use of custom loader string, virtualModules Map which contain pairs *.svelte.{index}.css: content and index to prevent key overlaps when compiling concurrently for SSR and browser.

The loader saves css string to the virtualModules Map and appends an import with custom loader string, relaunching svelte-loader with cssPath parameter, which makes it output css basically from the void (without a file) and pass it further to the .css loaders chain.

Every time css is read from the virtualModules Map it gets deleted to prevent leaks.

I'm currently using this approach in svelte-loader-hot on production.

Fixes #139, Fixes #131, Fixes #126

This wouldn't be possible without @trash-and-fire

syvb commented 3 years ago

Just tested this and it works great, but only when hotReload is disabled. When I make a change in watch mode it's reflected as soon as I reload. I do get errors whenever hotReload is enabled though.

non25 commented 3 years ago

Just tested this and it works great, but only when hotReload is disabled.

hotReload doesn't work on master. This PR's goal is not about fixing a hotReload. If we want hotReload, we should port svelte-loader-hot's changes here.

non25 commented 3 years ago

I'll make one slight change.

non25 commented 3 years ago

I've used compileOptions.filename instead of this.resource, because they are identical. Thus, other edits to tests are not required.

ghost commented 3 years ago

@non25 , can you please share your webpack config regarding this? emitCss: true, always fails for me irrespective of Prod or Dev environment. I followed your multiple PRs but not sure what is going wrong. Thanks in advance,

Here is my webpack config

    {
      test: /\.(svelte)$/,
      use: {
        loader: 'svelte-loader',
        options: {
          emitCss: true,
        },
      },
    },
    {
      test: /node_modules\/svelte\/.*\.mjs$/,
      resolve: {
        fullySpecified: false,
      },
    },
    {
      test: /\.css$/,
      use: [
        {
          loader: MiniCssExtractPlugin.loader,
        },
        {
          loader: 'css-loader',
          options: {
            url: false,
          },
        },
     ],
  },

Throws the following error:

TypeError: Cannot read property 'data' of undefined
at  \node_modules\svelte-loader\index.js:181:12
non25 commented 3 years ago

TypeError: Cannot read property 'data' of undefined at \node_modules\svelte-loader\index.js:181:12

It looks like you are still using published svelte-loader in npm. New changes are not there yet.

Install svelte-loader from current master branch:

# yarn 2
yarn add -D svelte-loader@sveltejs/svelte-loader
# npm
npm install -D sveltejs/svelte-loader

Also you can look at https://github.com/non25/webpack-svelte-tests for an inspiration.

ghost commented 3 years ago

@non25 , thank you for your quick response, I will test it now!

rwoodnz commented 3 years ago

I used the sveltejs/svelte-loader and the issues I was having went away. However, I am using Github Actions as a CI tool and it gives me "private repositor" build error message. I guess I am waiting for this to publish to NPM then, or is there a way to use this sort of repository from Github Actions? In the meantime I'm using the svelte-loader-hot and that's working ok.

kyrylkov commented 3 years ago

@rwoodnz v3 with webpack 5 support is published to npm already https://www.npmjs.com/package/svelte-loader

rwoodnz commented 3 years ago

https://www.npmjs.com/package/svelte-loader

Thanks! I will give it another go

rwoodnz commented 3 years ago

That works for me - good work! Should the install instructions save to dev dependencies instead?

kyrylkov commented 3 years ago

Should the install instructions save to dev dependencies instead?

Yes: npm install -D svelte-loader