Repository: huggingface/transformers.js (language: javascript)

Issue:
Transformers.js have bugs in next.js ( client-side )
### System Info

Transfomer.js version: "@huggingface/transformers": "^3.0.2"

Next.js version: "next": "14.2.5"

React version: "react": "^18",

OS that run next.js : windows11

### Environment/Platform

- [X] Website/web-app
- [ ] Browser extension
- [ ] Server-side (e.g., Node.js, Deno, Bun)
- [ ] Desktop app (e.g., Electron)
- [ ] Other (e.g., VSCode extension)

### Description

I'm very interested in the world of WebML and for me Transformer.js is one of the most promising libraries in this field, so I'd like to thank all the contributors to this library.

But right now I'm working on a personal project make in next.js and I've run into a lot of issues trying to get transformer.js to work in client-side components.

First when I set the configuration of next.js as the documentation states i.e.

```javascript

/** @type {import('next').NextConfig} */
const nextConfig = {
    // (Optional) Export as a static site
    // See https://nextjs.org/docs/pages/building-your-application/deploying/static-exports#configuration
    output: 'export', // Feel free to modify/remove this option

    // Override the default webpack configuration
    webpack: (config) => {
        // See https://webpack.js.org/configuration/resolve/#resolvealias
        config.resolve.alias = {
            ...config.resolve.alias,
            "sharp$": false,
            "onnxruntime-node$": false,
        }
        return config;
    },
}

module.exports = nextConfig

```

I get this error

```error
Module not found: Can't resolve './'
```

I get this error even if i make this configuration

```javascript
const nextConfig = {
  output: "standalone",
  // https://nextjs.org/docs/app/api-reference/next-config-js/serverExternalPackages
  serverExternalPackages: ["@huggingface/transformers"],
};
```
If i make this configuration  i have the same error of previously

The only configuration that work for me is 

```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',
  webpack: (config ) => {
    
    config.resolve.alias = {
      ...config.resolve.alias,
      "@huggingface/transformers": require.resolve("@huggingface/transformers"),
      "sharp$": false,
      "onnxruntime-node$": false,
    };
    return config;
  },
};

module.exports = nextConfig;
```

But after that I still have problems when I want to use the pipeline function to do text-generation with onnx-community/Llama-3.2-1B-Instruct as the documentation states https://huggingface.co/blog/llama32#transformersjs

my code :
```javascript
"use client"

export async function handleFreeMode(){
  const { pipeline } = await import("@huggingface/transformers")
    const generator = await pipeline("text-generation", "onnx-community/Llama-3.2-1B-Instruct");

    // Define the list of messages
    const messages = [
      { role: "system", content: "You are a helpful assistant." },
      { role: "user", content: "Tell me a joke." },
    ];

    // Generate a response
    const output = await generator(messages, { max_new_tokens: 128 });
    console.log(output[0].generated_text.at(-1).content);
    return output[0].generated_text.at(-1).content;
}
```

the error :
```error
transformers.cjs:3971 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'create')
    at createInferenceSession (transformers.cjs:3971:45)
    at eval (transformers.cjs:7090:108)
    at async Promise.all (:3000/fr/148/index 0)
    at async constructSessions (transformers.cjs:7087:31)
    at async Promise.all (:3000/fr/148/index 0)
    at async LlamaForCausalLM.from_pretrained (transformers.cjs:7643:20)
    at async AutoModelForCausalLM.from_pretrained (transformers.cjs:12826:20)
    at async Promise.all (:3000/fr/148/index 1)
    at async loadItems (transformers.cjs:17386:5)
    at async pipeline (transformers.cjs:17316:21)
    at async handleFreeMode (ClientSide.ts:5:23)
    at async handleSubmit (Chatbot.tsx:60:20)
  ``` 
    
    Thank you in advance if anyone in the community can help me solve this problem.

 


### Reproduction

1. Use next.js v14.2

2. Use transformer.js v3


Discussion / hints:
can you provide a minimal repo with the entire app? 
I encountered the same problem before, but I've now found a solution. 

## next.config.mjs:
```js
/** @type {import('next').NextConfig} */
import path from "path";
import {fileURLToPath} from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const nextConfig = {
    output: 'export',

    webpack: (config) => {
        config.resolve.alias['@huggingface/transformers'] = path.resolve(__dirname, 'node_modules/@huggingface/transformers');
        config.resolve.alias = {
            ...config.resolve.alias,
            "sharp$": false,
            "onnxruntime-node$": false,
        }
        return config;
    },
};

export default nextConfig;
```

I am experiencing the same issue
I had to remove --turbopack from "next dev --turbopack" for this to work.

> I encountered the same problem before, but I've now found a solution.
> 
> ## next.config.mjs:
> ```js
> /** @type {import('next').NextConfig} */
> import path from "path";
> import {fileURLToPath} from 'url';
> 
> const __filename = fileURLToPath(import.meta.url);
> const __dirname = path.dirname(__filename);
> 
> const nextConfig = {
>     output: 'export',
> 
>     webpack: (config) => {
>         config.resolve.alias['@huggingface/transformers'] = path.resolve(__dirname, 'node_modules/@huggingface/transformers');
>         config.resolve.alias = {
>             ...config.resolve.alias,
>             "sharp$": false,
>             "onnxruntime-node$": false,
>         }
>         return config;
>     },
> };
> 
> export default nextConfig;
> ```



Fix patch:
diff --git a/package.json b/package.json
index 4aad5f2f0..52fcececd 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
     "format:check": "prettier --check .",
     "typegen": "tsc --build",
     "dev": "webpack serve --no-client-overlay",
-    "build": "webpack && npm run typegen && rm ./dist/ort.bundle.min.mjs && cp ./node_modules/onnxruntime-web/dist/ort-wasm-simd-threaded.jsep.mjs ./dist",
+    "build": "webpack && npm run typegen",
     "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --verbose",
     "readme": "python ./docs/scripts/build_readme.py",
     "docs-api": "node ./docs/scripts/generate.js",
diff --git a/webpack.config.js b/webpack.config.js
index 8aff63d0d..7ad880868 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,9 +1,63 @@
 import TerserPlugin from "terser-webpack-plugin";
 import { fileURLToPath } from "url";
 import path from "path";
+import fs from "fs";
 
 const __dirname = path.dirname(fileURLToPath(import.meta.url));
 
+/**
+ * Plugin to post-process build files. Required to solve certain issues with ESM module output.
+ * See https://github.com/webpack/webpack/issues/17121 for more information.
+ * 
+ * @see https://webpack.js.org/contribute/writing-a-plugin/
+ */
+class PostBuildPlugin {
+
+  apply(compiler) {
+    compiler.hooks.done.tap('PostBuildPlugin', () => {
+      const dist = path.join(__dirname, 'dist');
+      const ORT_JSEP_FILE = 'ort-wasm-simd-threaded.jsep.mjs';
+      const ORT_BUNDLE_FILE = 'ort.bundle.min.mjs';
+
+      // 1. Remove unnecessary files
+      {
+        const file = path.join(dist, ORT_BUNDLE_FILE);
+        if (fs.existsSync(file)) fs.unlinkSync(file);
+      }
+      
+      // 2. Copy unbundled JSEP file
+      {
+        const src = path.join(__dirname, 'node_modules/onnxruntime-web/dist', ORT_JSEP_FILE);
+        const dest = path.join(dist, ORT_JSEP_FILE);
+        fs.copyFileSync(src, dest);
+      }
+
+      // 3. Replace strings in certain files
+      {
+        const files = ['transformers.js', 'transformers.min.js'];
+        for (const file of files) {
+          const filePath = path.join(dist, file);
+          let content = fs.readFileSync(filePath, 'utf8');
+          content = content.replace(
+            // Replace all instances of `new URL("./", import.meta.url)` with `new URL(import.meta.url)`,
+            // as it causes several issues with build tools and bundlers.
+            // 
+            // See the following issues for more information:
+            // - https://github.com/huggingface/transformers.js/issues/911
+            // - https://github.com/huggingface/transformers.js/issues/984
+            // - https://github.com/huggingface/transformers.js/issues/980
+            // - https://github.com/huggingface/transformers.js/issues/1021
+            // - https://github.com/huggingface/transformers.js/issues/1026
+            new RegExp('new URL\\(["\']\\.\\\/["\'],\\s*import\\.meta\\.url\\)', 'gm'),
+            "new URL(import.meta.url)",
+          );
+          fs.writeFileSync(filePath, content, 'utf8');
+        }
+      }
+    });
+  }
+}
+
 /**
  * Helper function to create webpack configurations.
  * @param {Object} options Options for creating a webpack target.
@@ -12,6 +66,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
  * @param {string} options.type Type of library.
  * @param {string} options.ignoreModules The list of modules to ignore.
  * @param {string} options.externalModules The list of modules to set as external.
+ * @param {Object[]} options.plugins List of plugins to use.
  * @returns {import('webpack').Configuration} One webpack target.
  */
 function buildConfig({
@@ -20,6 +75,7 @@ function buildConfig({
   type = "module", // 'module' | 'commonjs'
   ignoreModules = [],
   externalModules = [],
+  plugins = [],
 } = {}) {
   const outputModule = type === "module";
 
@@ -75,6 +131,7 @@ function buildConfig({
       },
       port: 8080,
     },
+    plugins,
   };
 
   if (outputModule) {
@@ -110,6 +167,7 @@ const NODE_EXTERNAL_MODULES = [
 // Web-only build
 const WEB_BUILD = buildConfig({
   type: "module",
+  plugins: [new PostBuildPlugin()],
 });
 
 // Node-compatible builds


Test patch: