Skip to content

Webpack fails with no error due to import keyword

I’m receiving a weird error npm ERR! code 1 when trying to launch the dev server or run a build.

I’ve researched this problem for a while with no success whatsoever.

The problem manifests itself when I try to import an image in a js file from the src folder.

import myImage from '../assets/images/my-image.svg'

Or when I try to import sass partials from the sass folder into app.scss.

@import './components/myComponent

Here is the NPM error message:

npm ERR! code 1
npm ERR! path /Users/david/Documents/Code/Project/crowdfund-product-page
npm ERR! command failed
npm ERR! command sh -c webpack serve

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/david/.npm/_logs/2021-03-26T11_43_57_401Z-debug.log

Here is a piece of the error output from the terminal:

        },
        properties: {
          asset: { '$ref': '#/definitions/AssetParserOptions' },
          'asset/inline': { '$ref': '#/definitions/EmptyParserOptions' },
          'asset/resource': { '$ref': '#/definitions/EmptyParserOptions' },
          'asset/source': { '$ref': '#/definitions/EmptyParserOptions' },
          javascript: { '$ref': '#/definitions/JavascriptParserOptions' },
          'javascript/auto': { '$ref': '#/definitions/JavascriptParserOptions' },
          'javascript/dynamic': { '$ref': '#/definitions/JavascriptParserOptions' },
          'javascript/esm': { '$ref': '#/definitions/JavascriptParserOptions' }
        }
      },
      Path: {
        description: 'The output directory as **absolute path** (required).',
        type: 'string',
        absolutePath: true
      },
      Pathinfo: {
        description: 'Include comments with information about the modules.',
        anyOf: [ { enum: [Array] }, { type: 'boolean' } ]
      },
      Performance: {
        description: 'Configuration for web performance recommendations.',
        anyOf: [
          { enum: [Array] },
          { '$ref': '#/definitions/PerformanceOptions' }
        ]
      },
      PerformanceOptions: {
        description: 'Configuration object for web performance recommendations.',
        type: 'object',
        additionalProperties: false,
        properties: {
          assetFilter: {
            description: 'Filter function to select assets that are checked.',
            instanceof: 'Function',
            tsType: 'Function'
          },
          hints: {
            description: 'Sets the format of the hints: warnings, errors or nothing at all.',
            enum: [Array]
          },
          maxAssetSize: {
            description: 'File size limit (in bytes) when exceeded, that webpack will provide performance hints.',
            type: 'number'
          },
          maxEntrypointSize: {
            description: 'Total size of an entry point (in bytes).',
            type: 'number'
          }
        }
      },
      Plugins: {
        description: 'Add additional plugins to the compiler.',
        type: 'array',
        items: {
          description: 'Plugin of type object or instanceof Function.',
          anyOf: [ [Object], [Object] ]
        }
      },
      Profile: {
        description: 'Capture timing information for each module.',
        type: 'boolean'
      },
      PublicPath: {
        description: "The 'publicPath' specifies the public URL address of the output files when referenced in a browser.",
        anyOf: [
          { enum: [Array] },
          { '$ref': '#/definitions/RawPublicPath' }
        ]
      },
      RawPublicPath: {
        description: "The 'publicPath' specifies the public URL address of the output files when referenced in a browser.",
        anyOf: [
          { type: 'string' },
          {
            instanceof: 'Function',
            tsType: '((pathData: import("../lib/Compilation").PathData, assetInfo?: import("../lib/Compilation").AssetInfo) => string)'
          }
        ]
      },
      RecordsInputPath: {
        description: 'Store compiler state to a json file.',
        anyOf: [ { enum: [Array] }, { type: 'string', absolutePath: true } ]
      },
      RecordsOutputPath: {
        description: 'Load compiler state from a json file.',
        anyOf: [ { enum: [Array] }, { type: 'string', absolutePath: true } ]
      },
      RecordsPath: {
        description: 'Store/Load compiler state from/to a json file. This will result in persistent ids of modules and chunks. An absolute path is expected. `recordsPath` is used for `recordsInputPath` and `recordsOutputPath` if they left undefined.',
        anyOf: [ { enum: [Array] }, { type: 'string', absolutePath: true } ]
      },
      Resolve: {
        description: 'Options for the resolver.',
        oneOf: [ { '$ref': '#/definitions/ResolveOptions' } ]
      },
      ResolveAlias: {
        description: 'Redirect module requests.',
        anyOf: [
          { type: 'array', items: [Object] },
          { type: 'object', additionalProperties: [Object] }
        ]
      },
      ResolveLoader: {
        description: 'Options for the resolver when resolving loaders.',
        oneOf: [ { '$ref': '#/definitions/ResolveOptions' } ]
      },
      ResolveOptions: {
        description: 'Options object for resolving requests.',
        type: 'object',
        additionalProperties: false,
        properties: {
          alias: { '$ref': '#/definitions/ResolveAlias' },
          aliasFields: {
            description: 'Fields in the description file (usually package.json) which are used to redirect requests inside the module.',
            type: 'array',
            items: [Object]
          },
          byDependency: {
            description: 'Extra resolve options per dependency category. Typical categories are "commonjs", "amd", "esm".',
            type: 'object',
            additionalProperties: [Object]
          },
          cache: {
            description: 'Enable caching of successfully resolved requests (cache entries are revalidated).',
            type: 'boolean'
          },
          cachePredicate: {
            description: 'Predicate function to decide which requests should be cached.',
            instanceof: 'Function',
            tsType: "((request: import('enhanced-resolve').ResolveRequest) => boolean)"
          },
          cacheWithContext: {
            description: 'Include the context information in the cache identifier when caching.',
            type: 'boolean'
          },
          conditionNames: {
            description: 'Condition names for exports field entry point.',
            type: 'array',
            items: [Object]
          },
          descriptionFiles: {
            description: 'Filenames used to find a description file (like a package.json).',
            type: 'array',
            items: [Object]
          },
          enforceExtension: {
            description: 'Enforce the resolver to use one of the extensions from the extensions option (User must specify requests without extension).',
            type: 'boolean'
          },
          exportsFields: {
            description: 'Field names from the description file (usually package.json) which are used to provide entry points of a package.',
            type: 'array',
            items: [Object]
          },
          extensions: {
            description: 'Extensions added to the request when trying to find the file.',
            type: 'array',
            items: [Object]
          },
          fallback: {
            description: 'Redirect module requests when normal resolving fails.',
            oneOf: [Array]
          },
          fileSystem: {
            description: 'Filesystem for the resolver.',
            tsType: "(import('../lib/util/fs').InputFileSystem)"
          },
          fullySpecified: {
            description: "Treats the request specified by the user as fully specified, meaning no extensions are added and the mainFiles in directories are not resolved (This doesn't affect requests from mainFields, aliasFields or aliases).",
            type: 'boolean'
          },
          importsFields: {
            description: 'Field names from the description file (usually package.json) which are used to provide internal request of a package (requests starting with # are considered as internal).',
            type: 'array',
            items: [Object]
          },
          mainFields: {
            description: 'Field names from the description file (package.json) which are used to find the default entry point.',
            type: 'array',
            items: [Object]
          },
          mainFiles: {
            description: 'Filenames used to find the default entry point if there is no description file or main field.',
            type: 'array',
            items: [Object]
          },
          modules: {
            description: 'Folder names or directory paths where to find modules.',
            type: 'array',
            items: [Object]
          },
          plugins: {
            description: 'Plugins for the resolver.',
            type: 'array',
            cli: [Object],
            items: [Object]
          },
          preferAbsolute: {
            description: "Prefer to resolve server-relative URLs (starting with '/') as absolute paths before falling back to resolve in 'resolve.roots'.",
            type: 'boolean'
          },
          preferRelative: {
            description: 'Prefer to resolve module requests as relative request and fallback to resolving as module.',
            type: 'boolean'
          },
          resolver: {
            description: 'Custom resolver.',
            tsType: "(import('enhanced-resolve').Resolver)"
          },
          restrictions: {
            description: 'A list of resolve restrictions. Resolve results must fulfill all of these restrictions to resolve successfully. Other resolve paths are taken when restrictions are not met.',
            type: 'array',
            items: [Object]
          },
          roots: {
            description: "A list of directories in which requests that are server-relative URLs (starting with '/') are resolved.",
            type: 'array',
            items: [Object]
          },
          symlinks: {
            description: 'Enable resolving symlinks to the original location.',
            type: 'boolean'
          },
          unsafeCache: {
            description: 'Enable caching of successfully resolved requests (cache entries are not revalidated).',
            anyOf: [Array]
          },
          useSyncFileSystemCalls: {
            description: 'Use synchronous filesystem calls for the resolver.',
            type: 'boolean'
          }
        }
      },
      ResolvePluginInstance: {
        description: 'Plugin instance.',
        type: 'object',
        additionalProperties: true,
        properties: {
          apply: {
            description: 'The run point of the plugin, required method.',
            instanceof: 'Function',
            tsType: "(resolver: import('enhanced-resolve').Resolver) => void"
          }
        },
        required: [ 'apply' ]
      },
      RuleSetCondition: {
        description: 'A condition matcher.',
        cli: { helper: true },
        anyOf: [
          { instanceof: 'RegExp', tsType: 'RegExp' },
          { type: 'string' },
          {
            type: 'object',
            additionalProperties: false,
            properties: [Object]
          },
          {
            instanceof: 'Function',
            tsType: '((value: string) => boolean)'
          },
          { '$ref': '#/definitions/RuleSetConditions' }
        ]
      },
      RuleSetConditionAbsolute: {
        description: 'A condition matcher matching an absolute path.',
        cli: { helper: true },
        anyOf: [
          { instanceof: 'RegExp', tsType: 'RegExp' },
          { type: 'string', absolutePath: true },
          {
            type: 'object',
            additionalProperties: false,
            properties: [Object]
          },
          {
            instanceof: 'Function',
            tsType: '((value: string) => boolean)'
          },
          { '$ref': '#/definitions/RuleSetConditionsAbsolute' }
        ]
      },
      RuleSetConditionOrConditions: {
        description: 'One or multiple rule conditions.',
        cli: { helper: true },
        anyOf: [
          { '$ref': '#/definitions/RuleSetCondition' },
          { '$ref': '#/definitions/RuleSetConditions' }
        ]
      },
      RuleSetConditionOrConditionsAbsolute: {
        description: 'One or multiple rule conditions matching an absolute path.',
        cli: { helper: true },
        anyOf: [
          { '$ref': '#/definitions/RuleSetConditionAbsolute' },
          { '$ref': '#/definitions/RuleSetConditionsAbsolute' }
        ]
      },
      RuleSetConditions: {
        description: 'A list of rule conditions.',
        type: 'array',
        items: { description: 'A rule condition.', oneOf: [ [Object] ] }
      },
      RuleSetConditionsAbsolute: {
        description: 'A list of rule conditions matching an absolute path.',
        type: 'array',
        items: {
          description: 'A rule condition matching an absolute path.',
          oneOf: [ [Object] ]
        }
      },
      RuleSetLoader: {
        description: 'A loader request.',
        type: 'string',
        minLength: 1
      },
      RuleSetLoaderOptions: {
        description: 'Options passed to a loader.',
        anyOf: [ { type: 'string' }, { type: 'object' } ]
      },
      RuleSetRule: {
        description: 'A rule description with conditions and effects for modules.',
        type: 'object',
        additionalProperties: false,
        properties: {
          compiler: {
            description: 'Match the child compiler name.',
            oneOf: [Array]
          },
          dependency: { description: 'Match dependency type.', oneOf: [Array] },
          descriptionData: {
            description: 'Match values of properties in the description file (usually package.json).',
            type: 'object',
            additionalProperties: [Object]
          },
          enforce: {
            description: 'Enforce this rule as pre or post step.',
            enum: [Array]
          },
          exclude: {
            description: 'Shortcut for resource.exclude.',
            oneOf: [Array]
          },
          generator: {
            description: 'The options for the module generator.',
            type: 'object'
          },
          include: {
            description: 'Shortcut for resource.include.',
            oneOf: [Array]
          },
          issuer: {
            description: 'Match the issuer of the module (The module pointing to this module).',
            oneOf: [Array]
          },
          issuerLayer: {
            description: 'Match layer of the issuer of this module (The module pointing to this module).',
            oneOf: [Array]
          },
          layer: {
            description: 'Specifies the layer in which the module should be placed in.',
            type: 'string'
          },
          loader: { description: 'Shortcut for use.loader.', oneOf: [Array] },
          mimetype: {
            description: 'Match module mimetype when load from Data URI.',
            oneOf: [Array]
          },
          oneOf: {
            description: 'Only execute the first matching rule in this array.',
            type: 'array',
            items: [Object]
          },
          options: {
            description: 'Shortcut for use.options.',
            cli: [Object],
            oneOf: [Array]
          },
          parser: {
            description: 'Options for parsing.',
            type: 'object',
            additionalProperties: true
          },
          realResource: {
            description: 'Match the real resource path of the module.',
            oneOf: [Array]
          },
          resolve: {
            description: 'Options for the resolver.',
            type: 'object',
            oneOf: [Array]
          },
          resource: {
            description: 'Match the resource path of the module.',
            oneOf: [Array]
          },
          resourceFragment: {
            description: 'Match the resource fragment of the module.',
            oneOf: [Array]
          },
          resourceQuery: {
            description: 'Match the resource query of the module.',
            oneOf: [Array]
          },
          rules: {
            description: 'Match and execute these rules when this rule is matched.',
            type: 'array',
            items: [Object]
          },
          sideEffects: {
            description: 'Flags a module as with or without side effects.',
            type: 'boolean'
          },
          test: {
            description: 'Shortcut for resource.test.',
            oneOf: [Array]
          },
          type: {
            description: 'Module type to use for the module.',
            type: 'string'
          },
          use: {
            description: 'Modifiers applied to the module when rule is matched.',
            oneOf: [Array]
          }
        }
      },
      RuleSetRules: {
        description: 'A list of rules.',
        type: 'array',
        items: { description: 'A rule.', anyOf: [ [Object], [Object] ] }
      },
      RuleSetUse: {
        description: 'A list of descriptions of loaders applied.',
        anyOf: [
          { type: 'array', items: [Object] },
          {
            instanceof: 'Function',
            tsType: '((data: { resource: string, realResource: string, resourceQuery: string, issuer: string, compiler: string }) => RuleSetUseItem[])'
          },
          { '$ref': '#/definitions/RuleSetUseItem' }
        ]
      },
      RuleSetUseItem: {
        description: 'A description of an applied loader.',
        anyOf: [
          {
            type: 'object',
            additionalProperties: false,
            properties: [Object]
          },
          {
            instanceof: 'Function',
            tsType: '((data: object) => RuleSetUseItem|RuleSetUseItem[])'
          },
          { '$ref': '#/definitions/RuleSetLoader' }
        ]
      },
      ScriptType: {
        description: 'This option enables loading async chunks via a custom script type, such as script type="module".',
        enum: [ false, 'text/javascript', 'module' ]
      },
      SnapshotOptions: {
        description: 'Options affecting how file system snapshots are created and validated.',
        type: 'object',
        additionalProperties: false,
        properties: {
          buildDependencies: {
            description: 'Options for snapshotting build dependencies to determine if the whole cache need to be invalidated.',
            type: 'object',
            additionalProperties: false,
            properties: [Object]
          },
          immutablePaths: {
            description: 'List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.',
            type: 'array',
            items: [Object]
          },
          managedPaths: {
            description: 'List of paths that are managed by a package manager and can be trusted to not be modified otherwise.',
            type: 'array',
            items: [Object]
          },
          module: {
            description: 'Options for snapshotting dependencies of modules to determine if they need to be built again.',
            type: 'object',
            additionalProperties: false,
            properties: [Object]
          },
          resolve: {
            description: 'Options for snapshotting dependencies of request resolving to determine if requests need to be re-resolved.',
            type: 'object',
            additionalProperties: false,
            properties: [Object]
          },
          resolveBuildDependencies: {
            description: 'Options for snapshotting the resolving of build dependencies to determine if the build dependencies need to be re-resolved.',
            type: 'object',
            additionalProperties: false,
            properties: [Object]
          }
        }
      },
      SourceMapFilename: {
        description: "The filename of the SourceMaps for the JavaScript files. They are inside the 'output.path' directory.",
        type: 'string',
        absolutePath: false
      },
      SourcePrefix: {
        description: 'Prefixes every line of the source in the bundle with this string.',
        type: 'string'
      },
      StatsOptions: {
        description: 'Stats options object.',
        type: 'object',
        additionalProperties: false,
        properties: {
          all: {
            description: 'Fallback value for stats options when an option is not defined (has precedence over local webpack defaults).',
            type: 'boolean'
          },
          assets: { description: 'Add assets information.', type: 'boolean' },
          assetsSort: {
            description: 'Sort the assets by that field.',
            type: 'string'
          },
          assetsSpace: {
            description: 'Space to display assets (groups will be collapsed to fit this space).',
            type: 'number'
          },
          builtAt: {
            description: 'Add built at time information.',
            type: 'boolean'
          },
          cached: {
            description: "Add information about cached (not built) modules (deprecated: use 'cachedModules' instead).",
            type: 'boolean'
          },
          cachedAssets: {
            description: 'Show cached assets (setting this to `false` only shows emitted files).',
            type: 'boolean'
          },
          cachedModules: {
            description: 'Add information about cached (not built) modules.',
            type: 'boolean'
          },
          children: { description: 'Add children information.', type: 'boolean' },
          chunkGroupAuxiliary: {
            description: 'Display auxiliary assets in chunk groups.',
            type: 'boolean'
          },
          chunkGroupChildren: {
            description: 'Display children of chunk groups.',
            type: 'boolean'
          },
          chunkGroupMaxAssets: {
            description: 'Limit of assets displayed in chunk groups.',
            type: 'number'
          },
          chunkGroups: {
            description: 'Display all chunk groups with the corresponding bundles.',
            type: 'boolean'
          },
          chunkModules: {
            description: 'Add built modules information to chunk information.',
            type: 'boolean'
          },
          chunkModulesSpace: {
            description: 'Space to display chunk modules (groups will be collapsed to fit this space, value is in number of modules/group).',
            type: 'number'
          },
          chunkOrigins: {
            description: 'Add the origins of chunks and chunk merging info.',
            type: 'boolean'
          },

webpack.config.js file:

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const ESLintPlugin = require('eslint-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

const isDevelopment = process.env.NODE_ENV !== 'production'

module.exports = {
    mode: isDevelopment ? 'development' : 'production',
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        publicPath: '',
        filename: isDevelopment ? '[name].js' : '[name].[hash].js',
    },
    devServer: {
        contentBase: './src',
        open: 'Google Chrome',
        compress: true,
        port: 9000,
        hot: true,
    },
    module: {
        rules: [
            {
                test: /.js$/,
                exclude: /(node_modules)/,
                use: 'babel-loader',
            },
            {
                test: /.(sa|sc|c)ss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true,
                        },
                    },
                    {
                        loader: 'postcss-loader',
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: true,
                            implementation: require('sass'),
                        },
                    },
                ],
            },
            {
                test: /.(?:ico|gif|png|jpg|jpeg)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'assets/images/[hash][ext][query]',
                },
            },
            {
                test: /.(woff(2)?|eot|ttf|otf|svg|)$/,
                type: 'asset/inline',
                generator: {
                    filename: 'fonts/[hash][ext][query]',
                },
            },
        ],
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            title: 'Webpack template',
            template: '/src/index.html',
            filename: 'index.html',
        }),
        new CopyPlugin({
            patterns: [{ from: 'src/assets/static', to: 'assets/static' }],
        }),
        new MiniCssExtractPlugin({
            filename: 'main.css',
        }),
        new ESLintPlugin(),
    ],
}

package.json file:

"scripts": {
    "start": "webpack serve",
    "dev": "cross-env NODE_ENV=development webpack --config webpack.config.js",
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
    "deploy": "npm run build && gh-pages -d dist"
},
"dependencies": {
    "autoprefixer": "^10.2.5",
    "cssnano": "^4.1.10",
    "gh-pages": "^3.1.0"
},
"devDependencies": {
    "@babel/core": "^7.13.10",
    "@babel/eslint-parser": "^7.13.10",
    "@babel/preset-env": "^7.13.12",
    "babel-loader": "^8.2.2",
    "clean-webpack-plugin": "^3.0.0",
    "copy-webpack-plugin": "^8.1.0",
    "cross-env": "^7.0.3",
    "css-loader": "^5.2.0",
    "eslint": "^7.22.0",
    "eslint-config-airbnb-base": "^14.2.1",
    "eslint-plugin-import": "^2.22.1",
    "eslint-webpack-plugin": "^2.5.3",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.3.1",
    "mini-css-extract-plugin": "^1.3.9",
    "postcss-loader": "^5.2.0",
    "sass": "^1.32.8",
    "sass-loader": "^11.0.1",
    "style-loader": "^2.0.0",
    "webpack": "^5.28.0",
    "webpack-cli": "^4.5.0",
    "webpack-dev-server": "^3.11.2"
},

Answer

Problem solved by removing the generator from the font import in webpack.config.js, going from this :

test: /.(woff(2)?|eot|ttf|otf|svg|)$/,
type: 'asset/inline'
generator: {
    filename: 'assets/images/[hash][ext][query]'
}

To this :

test: /.(woff(2)?|eot|ttf|otf|svg|)$/,
type: 'asset/inline'