oxc-project/oxc · warning

Unexpected `!` in `{name}`.

Error message

Unexpected `!` in `{name}`.

What it means

This is oxlint's 'import/no-webpack-loader-syntax' diagnostic. It reports any import or require whose module string contains an exclamation mark, the webpack loader syntax (e.g. import 'babel-loader!./file.js'). Inline loader syntax couples application code to webpack and is ignored or rejected by other bundlers, toolchains, and Node itself, so the rule forbids it.

Source

Thrown at crates/oxc_linter/src/rules/import/no_webpack_loader_syntax.rs:13

use oxc_ast::{
    AstKind,
    ast::{Argument, Expression},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::AstNode;
use oxc_span::Span;

use crate::{context::LintContext, rule::Rule};

fn no_named_as_default_diagnostic(name: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!("Unexpected `!` in `{name}`."))
        .with_help("Do not use import syntax to configure webpack loaders")
        .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct NoWebpackLoaderSyntax;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Forbids using Webpack loader syntax directly in import or require statements.
    ///
    /// ### Why is this bad?
    ///
    /// This loader syntax is non-standard, so it couples the code to Webpack. The recommended way to
    /// specify Webpack loader configuration is in a [Webpack configuration file](https://webpack.js.org/concepts/loaders/#configuration).
    ///
    /// ### Examples

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Move the loader configuration into the bundler config file (webpack.config.js module.rules, or the equivalent in Vite/esbuild) and import the plain resource: import './app.css'.
  2. For raw text or assets, use the toolchain's convention (e.g. '?raw' suffix in Vite, asset modules in webpack 5) instead of raw-loader! syntax.
  3. If the file must stay webpack-only and you accept the coupling, disable the rule for that file with an oxlint-disable comment.

Example fix

// before
import 'raw-loader!./data.txt';
const css = require('style-loader!css-loader!./app.css');

// after (webpack 5 asset modules in webpack.config.js)
import data from './data.txt';
import './app.css';
Defensive patterns

Strategy: validation

Validate before calling

# catch webpack loader syntax before linters or other bundlers do
rg -n "(import|require)\s*\(?\s*['\"][^'\"]*![^'\"]*['\"]" src/

Prevention

When it happens

Trigger: Enable the rule and lint code where an ImportDeclaration source or a require() string literal contains '!', such as 'style-loader!css-loader!./app.css' or 'raw-loader!./data.txt'. The diagnostic names the offending module string in {name}.

Common situations: Projects migrating off webpack to Vite, esbuild, vitest, or Node ESM hit this because those tools do not understand loader chains in the specifier. Copy-pasted older webpack recipes (raw-loader, babel-loader inline, !!style-loader!css-loader!) are the usual sources.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/4b58008a65cba968. Report an issue: GitHub.