storeon/svelte

useStoreon working incorrectly in browser

kytta opened this issue · 4 comments

kytta commented

I develop an app with Svelte and use Storeon. After compiling the code and running in browser, I get an error:

Uncaught ReferenceError: process is not defined
    at useStoreon (index.js:11)
    at instance$a (App.svelte:9)
    at init (index.mjs:1385)
    at new App (App.svelte:9)
    at index.js:5
    at index.js:7

process is used only once in the whole module, in this check:

svelte/index.js

Lines 11 to 16 in 4de2bd1

if (process.env.NODE_ENV !== 'production' && !store) {
throw new Error(
'Could not find storeon context value.' +
'Please ensure you provide store using "provideStoreon" function'
)
}

Why is there even a reference to process when Svelte is supposed to be compiled for browser? Is this a bug or is my build perhaps set up improperly?

Hi. The module is supposed to be built by some builders (webpack, parcel, rollup), Svelte itself is supposed to be compiled. During the building process, all expression below process property will be cut out from the bundle. Please provide your build config to help understand the situation.

kytta commented

Hi, sorry for my late reply. Here's what my Rollup config looks like:

import RPBabel from 'rollup-plugin-babel';
import RPCommonJs from '@rollup/plugin-commonjs';
import RPBundleHtml from 'rollup-plugin-bundle-html';
import RPPostCss from 'rollup-plugin-postcss';
import RPNodeResolve from '@rollup/plugin-node-resolve';
import RPSvelte from 'rollup-plugin-svelte';
import { terser as RPTerser } from 'rollup-plugin-terser';

const svelteOptions = require('./svelte.config');

const isDevelopment = process.env.NODE_ENV === 'development' || false;

const plugins = [
    RPSvelte(svelteOptions),
    RPBundleHtml({
        template: 'src/index.html',
        dest: 'dist',
        filename: 'index.html',
    }),
    RPPostCss({
        extract: true,
    }),
    RPNodeResolve({
        browser: true,
        dedupe: importee =>
            importee === 'svelte' || importee.startsWith('svelte/'),
    }),
    RPCommonJs(),
    !isDevelopment && RPBabel({
        extensions: [ '.js', '.mjs', '.html', '.svelte' ],
        exclude: [ /\/@babel\// ],
        presets: [
            [
                '@babel/preset-env',
                {
                    targets: '[REDACTED DUE TO LENGTH]',
                }
            ]
        ],
    }),
    !isDevelopment && RPTerser({
        compress: {
            drop_console: true
        },
        output: {
            comments: false
        },
        sourcemap: false,
    }),
];

module.exports = {
    input: 'src/index.js',
    output: {
        file: 'dist/index.js',
        sourcemap: isDevelopment,
        format: 'iife',
        name: 'REDACTED',
    },
    plugins,
    watch: {
        clearScreen: false,
    },
};

As I see, you need to define NODE_ENV global constant.
So you can use this plugin:

import replace from '@rollup/plugin-replace'

export default {
  plugins: [
    replace({
      'process.env.NODE_ENV': JSON.stringify(production ? 'production' : 'development')
    }),
  ],
};
kytta commented

Ah, I see. Thank you, it's all resolved now!