vue-component-compiler icon indicating copy to clipboard operation
vue-component-compiler copied to clipboard

btoa in css source break SSR

Open LukasBombach opened this issue 5 years ago • 6 comments

This line

        if (${e(compiler.template.isProduction)} && css.map) {
          // https://developer.chrome.com/devtools/docs/javascript-debugging
          // this makes source maps inside style tags work properly in Chrome
          code += '\\n/*# sourceURL=' + css.map.sources[0] + ' */'
          // http://stackoverflow.com/a/26603875
          code +=
            '\\n/*# sourceMappingURL=data:application/json;base64,' +
            btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) +
            ' */'
        }

https://github.com/vuejs/vue-component-compiler/blob/master/src/assembler.ts#L116

breaks SSR because btoa is not available in the global namespace of node.

If you add a check here, SSR will work.

LukasBombach avatar Jul 03 '19 15:07 LukasBombach

Just a +1, having the same issue when rolling a Vue component with the following rollup-plugin-vue config. Backtracked the btoa-issue to the vue-component-compiler.

(using the following config)

import vue from 'rollup-plugin-vue'; // Handle .vue SFC files
import buble from 'rollup-plugin-buble'; // Transpile/polyfill with reasonable browser support
import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
import rollupJson from 'rollup-plugin-json';
import { terser } from 'rollup-plugin-terser';

export default commandLineArgs => {
    return {
        input: 'src/index.js', // Path relative to package.json
        output: {
            name: 'Icon',
            exports: 'named',
            globals: {
                vue: 'Vue'
            }
        },
        external: ['vue'],
        plugins: [
            resolve({ preferBuiltins: true }),
            rollupJson(),
            commonjs(),
            vue({
                css: true, // Dynamically inject css as a <style> tag
                compileTemplate: true, // Explicitly convert template to render function
                template: {
                    isProduction: true,
                    optimizeSSR: commandLineArgs.format === 'umd'
                }
            }),
            buble({
                objectAssign: 'Object.assign',
                exclude: 'node_modules/**'
            }),
            terser()
        ]
    };
};

FreekVR avatar Oct 16 '19 10:10 FreekVR

i have the same issue

cannap avatar Dec 11 '19 13:12 cannap

I'm facing the same issue (with rollup), did any of you find a workaround ?

Thanks

sydney-d avatar Jan 20 '20 12:01 sydney-d

The precise error is: ReferenceError: btoa is not defined and it is still an active problem. I'm hitting it in a Gridsome-based project that does static rendering.

It looks like the following solution from StackOverflow can be applied in the case that the runtime is Node.js https://stackoverflow.com/a/47890385

I tested the following change locally

if (typeof boa === 'undefined') {
    code += '\n/*# sourceMappingURL=data:application/json;base64,' + Buffer.from(unescape(encodeURIComponent(JSON.stringify(css.map))), 'binary').toString('base64') + ' */';
} else {
    code += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) + ' */';
}

Unfortunately, this is far from the only place the assembler assumes it's running in a browser. For example, there are multiple references to the document variable.

esoterra avatar Oct 26 '20 04:10 esoterra

Are there any updates around this? It's absolutely killing us :(

tibineagu avatar Jul 05 '21 17:07 tibineagu

Run into the same problem and it's almost killing me :(

HADB avatar Oct 15 '21 02:10 HADB