PepsRyuu / rollup-plugin-hot-css

MIT License
6 stars 3 forks source link

Input sourcemap missing in custom loader #2

Open ksesong opened 4 years ago

ksesong commented 4 years ago

While trying to use sourcemaps in a custom loader, I realised that the sourcemap did not exist as input.map as suggested by the documentation but as a concatenated base64-encoded string in the code input.code.

      loaders: [
        function (input) {
          console.log(input); // input.map does not exist, but a b64 sourcemap is included in input.code
          return input;
        },
      ]

More, sourcemaps never appear in the final code, whether they are inline in the source file, or if I try to read them in a custom loader and add them as object to input.map. This may be due to my configuration, but I can't manage to find a reason, my .rollup.config.js being quite simple.

{
  input: './src/main.tsx',
  output: {
    dir: 'dist',
    format: 'esm',
    entryFileNames: '[name].[hash].js',
    assetFileNames: '[name].[hash][extname]',
  },
  plugins: [
    /* ... */
    hotcss({
      hot: process.env.NODE_ENV === 'development',
      filename: 'styles.css',
      loaders: [
        function(input) {
          console.log(input);
          return input;
        },
      ],
    }),
    babel({ extensions, babelHelpers: 'bundled' }),
    url(),
  ],
}
PepsRyuu commented 4 years ago

Thanks for the report.

Some initial thoughts, I think a sourcemap: true flag can be added. There was no intention initially of providing sourcemaps in the output since I rarely use them. I don't think it should be default behaviour however. While individual source maps can be collapsed and cached, the problem is that on a rebuild, all of those source maps will have to be collapsed for the entire file on every rebuild. This sounds like it could be computationally expensive.

This seems like quite a challenge to get this working correctly and to write test cases for all of the different source map scenarios. Not sure when I'll be able to address it.

piotr-cz commented 4 years ago

According to rollup docs source maps should be passed in the transformer however this is not enough.

return {
    code: SIDE_EFFECT_CODE,
    map: input.map,
    moduleSideEffects: true
};

sourceMap should probably be emitted separately in generateBundle, this is how far I got.

piotr-cz commented 4 years ago

Here is the diff: https://github.com/PepsRyuu/rollup-plugin-hot-css/compare/master...piotr-cz:feature/source-maps

PepsRyuu commented 4 years ago

@piotr-cz If I'm reading the PR correctly, that will only give you the last generated source map for 1 CSS file. It won't give you a source map for all of the CSS files that are included in the generated .css file. Whichever CSS file was the last to run through the transform function will be the source map.

piotr-cz commented 4 years ago

Yes, you are probably right. I don't have enough knowledge about writing rollup plugins and this is not so easy as I thought.

piotr-cz commented 4 years ago

When looking at the source code of rollup-plugin-styles plugin, it looks like that adding source maps is rather non-trivial task.

I've decided to use rollup-plugin-hot-css with custom loader when hmr flag is on (process.env.NOLLUP === 'true') and rollup-plugin-styles for production builds.

With little tweaking both can read options from one postcss.config.js file.

piotr-cz commented 4 years ago

As an example, this is simplified version of my rollup.conig.js file:

import rollupPluginStyles from 'rollup-plugin-styles'
import rollupPluginHotCss from 'rollup-plugin-hot-css'

export default({
  // ...
  plugins: [
    process.env.NOLLUP === 'true'
      ? rollupPluginHotCss({ file: 'index.css' })
      : rollupPluginStyles({
          minimize: process.env.NODE_ENV === 'production',
          mode: 'extract',
          sourceMap: { inline: false },
        })
  ]
})