11import TerserPlugin from "terser-webpack-plugin" ;
22import { fileURLToPath } from "url" ;
33import path from "path" ;
4+ import fs from "fs" ;
45
56const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) ) ;
67
8+ /**
9+ * Plugin to post-process build files. Required to solve certain issues with ESM module output.
10+ * See https://github.com/webpack/webpack/issues/17121 for more information.
11+ *
12+ * @see https://webpack.js.org/contribute/writing-a-plugin/
13+ */
14+ class PostBuildPlugin {
15+
16+ apply ( compiler ) {
17+ compiler . hooks . done . tap ( 'PostBuildPlugin' , ( ) => {
18+ const dist = path . join ( __dirname , 'dist' ) ;
19+ const ORT_JSEP_FILE = 'ort-wasm-simd-threaded.jsep.mjs' ;
20+ const ORT_BUNDLE_FILE = 'ort.bundle.min.mjs' ;
21+
22+ // 1. Remove unnecessary files
23+ {
24+ const file = path . join ( dist , ORT_BUNDLE_FILE ) ;
25+ if ( fs . existsSync ( file ) ) fs . unlinkSync ( file ) ;
26+ }
27+
28+ // 2. Copy unbundled JSEP file
29+ {
30+ const src = path . join ( __dirname , 'node_modules/onnxruntime-web/dist' , ORT_JSEP_FILE ) ;
31+ const dest = path . join ( dist , ORT_JSEP_FILE ) ;
32+ fs . copyFileSync ( src , dest ) ;
33+ }
34+
35+ // 3. Replace strings in certain files
36+ {
37+ const files = [ 'transformers.js' , 'transformers.min.js' ] ;
38+ for ( const file of files ) {
39+ const filePath = path . join ( dist , file ) ;
40+ let content = fs . readFileSync ( filePath , 'utf8' ) ;
41+ content = content . replace (
42+ // Replace all instances of `new URL("./", import.meta.url)` with `new URL(import.meta.url)`,
43+ // as it causes several issues with build tools and bundlers.
44+ //
45+ // See the following issues for more information:
46+ // - https://github.com/huggingface/transformers.js/issues/911
47+ // - https://github.com/huggingface/transformers.js/issues/984
48+ // - https://github.com/huggingface/transformers.js/issues/980
49+ // - https://github.com/huggingface/transformers.js/issues/1021
50+ // - https://github.com/huggingface/transformers.js/issues/1026
51+ new RegExp ( 'new URL\\(["\'].\\\/["\'],\\s*import\\.meta\\.url\\)' , 'gm' ) ,
52+ "new URL(import.meta.url)" ,
53+ ) ;
54+ fs . writeFileSync ( filePath , content , 'utf8' ) ;
55+ }
56+ }
57+ } ) ;
58+ }
59+ }
60+
761/**
862 * Helper function to create webpack configurations.
963 * @param {Object } options Options for creating a webpack target.
@@ -12,6 +66,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
1266 * @param {string } options.type Type of library.
1367 * @param {string } options.ignoreModules The list of modules to ignore.
1468 * @param {string } options.externalModules The list of modules to set as external.
69+ * @param {Object[] } options.plugins List of plugins to use.
1570 * @returns {import('webpack').Configuration } One webpack target.
1671 */
1772function buildConfig ( {
@@ -20,6 +75,7 @@ function buildConfig({
2075 type = "module" , // 'module' | 'commonjs'
2176 ignoreModules = [ ] ,
2277 externalModules = [ ] ,
78+ plugins = [ ] ,
2379} = { } ) {
2480 const outputModule = type === "module" ;
2581
@@ -75,6 +131,7 @@ function buildConfig({
75131 } ,
76132 port : 8080 ,
77133 } ,
134+ plugins,
78135 } ;
79136
80137 if ( outputModule ) {
@@ -110,6 +167,7 @@ const NODE_EXTERNAL_MODULES = [
110167// Web-only build
111168const WEB_BUILD = buildConfig ( {
112169 type : "module" ,
170+ plugins : [ new PostBuildPlugin ( ) ] ,
113171} ) ;
114172
115173// Node-compatible builds
0 commit comments