vuejs / vue-component-compiler

Compile a single file Vue component into a CommonJS module.
MIT License
343 stars 52 forks source link

btoa in css source break SSR #88

Open LukasBombach opened 5 years ago

LukasBombach commented 5 years ago

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.

FreekVR commented 5 years ago

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()
        ]
    };
};
cannap commented 4 years ago

i have the same issue

sydney-d commented 4 years ago

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

Thanks

esoterra commented 4 years ago

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.

tibineagu commented 3 years ago

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

HADB commented 3 years ago

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