Plugins: Rollup import of images compiling as a const in build file

Created on 31 Jan 2020  路  6Comments  路  Source: rollup/plugins

  • Rollup Plugin Name: @rollup/plugin-image
  • Rollup Plugin Version: ^2.0.1
  • Rollup Version: ^1.31.0
  • Operating System (or Browser): iPad Mini 9.3.5 (Safari)
  • Node Version: v10.16.2

How Do We Reproduce?

Import image in react component

import twoMinOrangeSvg from '../../img/supporting/2-min-orange.svg';

Using the following config

import babel from 'rollup-plugin-babel';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import postcss from 'rollup-plugin-postcss';
import filesize from 'rollup-plugin-filesize';
import autoprefixer from 'autoprefixer';
import localResolve from 'rollup-plugin-local-resolve';
import json from 'rollup-plugin-json';
import pkg from './package.json';
import externals from 'rollup-plugin-node-externals';
import builtins from 'rollup-plugin-node-builtins';
import globals from 'rollup-plugin-node-globals';
import image from '@rollup/plugin-image';
import { terser } from 'rollup-plugin-terser';

const ENVIRONMENT = process.env.ENVIRONMENT;
const PRODUCTION = ENVIRONMENT === 'production';

const config = {
  input: 'src/index.js',
  watch: {
    chokidar: {
        usePolling: true,
        paths: 'src/**'
    }
  },
  output:
   [
    {
      file: pkg.browser,
      format: 'umd',
      name: 'Example',
    },
    {
      file: pkg.main,
      format: 'cjs',
      name: 'Example',
    },
    {
      file: pkg.module,
      format: 'es',
    },
  ],
  external: [
    'react',
    'react-dom',
    'styled-components',
    'formik',
    'scheduler',
    'date-fns'
  ],
  globals: {
      // Use external version of React
      "react": "React"
  },
  plugins: [
    PRODUCTION &&  globals(),
    PRODUCTION &&  builtins(),
    PRODUCTION &&  externals(),
    babel({ exclude: 'node_modules/**', presets: ['@babel/env', '@babel/preset-react'] }),
    PRODUCTION &&  commonjs({
      namedExports: {
        // left-hand side can be an absolute path, a path
        // relative to the current directory, or the name
        // of a module in node_modules
        'node_modules/formik/node_modules/scheduler/index.js' : ['unstable_runWithPriority'],
      }
    }),
    PRODUCTION && peerDepsExternal(),
    PRODUCTION && postcss({ extract: true, plugins: [autoprefixer] }),
    PRODUCTION && json({  include: 'node_modules/**' }),
    PRODUCTION && localResolve(),
    PRODUCTION && resolve({dedupe: [ 'react', 'react-dom' ]}),
    PRODUCTION && filesize(),
    image(),
    PRODUCTION && terser()
  ]
};

export default config;

Expected Behavior

Image import to compile as a var in build file

Actual Behavior

In the console I get the following error

Unexpected keyword 'const'. Const declarations are not supported in strict mode.

in my build index.js file this compiles to the svg as a const, instead of a var

const img = 'data:image/svg+xml;utf-8,<?xml version="1.0" encoding="utf-8"?><!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"  viewBox="0 0 40 40" style="enable-background:new 0 0 40 40;" xml:space="preserve">....path code here.....</svg>';
t鹿 馃悶 bug 馃攲 plugin-image

Most helpful comment

Ok, I know what is going on - this just happens because the transformed file still has .svg extension and Babel is not instructed to transpile those (otherwise it would often crash on unexpected syntax etc), you can fix this by adding .svg to extensions:

import babel from 'rollup-plugin-babel';
import image from '@rollup/plugin-image';

const config = {
  input: 'src/index.js',
  output: {
    file: 'output/bundle.js',
    format: 'cjs'
  },
  plugins: [
    image(),
    babel({
      exclude: 'node_modules/**',
      presets: ['@babel/env', '@babel/preset-react'],
      extensions: ['.js', '.svg'],
    }),
  ]
};

export default config;

All 6 comments

Thanks for opening an issue. A few things:

  1. I see that you're using a number of deprecated plugins, you'll want to remedy that before we can triage.
  2. The code you provided is appreciated, but does not meet our requirements for a minimal reproduction, as noted in the issue template.

It looks like the image plugin is doing what it's supposed to, but the const isn't being converted to var somewhere else. The issue is more than likely how you're using that plugin stack, but we won't be able to triage until you boil that down to a minimal reproduction and provide a good one.

So, I think I've located the issue.

The import

import twoMinOrangeSvg from '../../img/supporting/2-min-orange.svg';

Points to a directory that must be outside what babel is attempting to compile. Moving the image into the same directory

import svg from '.close-icon.svg';

compiles to

var svg = _interopDefault(require('.close-icon.svg'));

However, the following (with the / in front of the filename)

import svg from '.close-icon.svg';

compiles to

const img = 'data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="25" height="26" viewBox="0 0 25 26"> .....</svg>';

I made a REPL with a pretty barebones config with both kind of imports where you can see the bundled file.

Updated config

import babel from 'rollup-plugin-babel';
import image from '@rollup/plugin-image';

const config = {
  input: 'src/index.js',
  output: {
    file: 'output/bundle.js',
    format: 'cjs'
  },
  plugins: [
    babel({ exclude: 'node_modules/**', presets: ['@babel/env', '@babel/preset-react'] }),
    image(),
  ]
};

export default config;

Any suggestions?

Thanks for looking into it. This looks like it might be an issue with the babel plugin (which we haven't migrated here just yet), because the output from image still looks good. @Andarist any thoughts? We'll take a look at the REPL as soon as we're able to try and narrow it down further.

Ill take a look at this.

Ok, I know what is going on - this just happens because the transformed file still has .svg extension and Babel is not instructed to transpile those (otherwise it would often crash on unexpected syntax etc), you can fix this by adding .svg to extensions:

import babel from 'rollup-plugin-babel';
import image from '@rollup/plugin-image';

const config = {
  input: 'src/index.js',
  output: {
    file: 'output/bundle.js',
    format: 'cjs'
  },
  plugins: [
    image(),
    babel({
      exclude: 'node_modules/**',
      presets: ['@babel/env', '@babel/preset-react'],
      extensions: ['.js', '.svg'],
    }),
  ]
};

export default config;

Awesome, thank you. I'll make sure we add that to the README.

Was this page helpful?
0 / 5 - 0 ratings