onnxruntime/js/web/webpack.config.js
Changming Sun 6cdf071a94
Cherry-picks to the release branch (#16017)
### Description
Cherry-picks 26 commits to the release branch. 
Most cherry-picks are clean merges. Except:

1. When I got conflicts in cgmanifest.json and download-deps.yml, I
choose to ignore the conflicts and regenerate the two files
2. There were some conflicts in cmake/deps.txt, onnxruntime_c_api.cc


PR list:

[js/webgpu] fix Transpose with non-float tensor (#15819)
[js/web] fix terser reserved symbols for worker (#15864)
[JSEP] fix constructor for OrtDevice (#15805)
Bump engine.io from 6.4.1 to 6.4.2 in /js/web (#15799)
Bump engine.io from 6.4.0 to 6.4.2 in /onnxruntime/test/wasm (#15798)
[wasm] revert emsdk to v3.1.19 (#15793)
[wasm/JSEP] add threaded build to artifacts (#15777)
[js/web] add target ort.webgpu.min.js (#15780)
update ort extensions to 94142d8391c9791ec71c38336436319a2d4ac7a0 (#15688)
fix: setting builder optimization level to TRT 8.6 default (#15897)
Adust GetVersionString() GetBuildInfoString() signatures and move them to OrtApi (#15921)
Fix segfault for multiple GPU run (regression) (#15823)
android package fix (#15999)
[CoreML EP] Minor changes to allow CoreML EP to handle more nodes and models. (#15993)
Adding support for conv fp16 fusion on Resnet50v1 (#15474)
update onnx release 1.14 for docker files (#15680)
Avoid generating training documentation during packaging (#15795)
Update Conv-Add-Relu Fusion Transformation (#15834)
Fix symbolic shape infer empty value_info (#15842)
NhwcFusedConv: Add before Activation (#15837)
use __hmul2 instead of __hmul2_rn (#15852)
change the EP device to default OrtDevice() for memoryType equals CPU Input (#15903)
Fixing NhwcFusedConv fp16 (#15950)
fix topo sort in quantization tool (#16003)
[doc] add LeakyRelu to coreml supported ops (#15944)
[DML EP] Add frequent upload heap flushing (#15960)

Co-authored-by: Yulong Wang 
Co-authored-by: dependabot[bot] 
Co-authored-by: Guenther Schmuelling 
Co-authored-by: Shalva Mist 
Co-authored-by: Maximilian Müller 
Co-authored-by: Dmitri Smirnov 
Co-authored-by: pengwa 
Co-authored-by: Ashwini Khade 
Co-authored-by: Edward Chen 
Co-authored-by: Jian Chen 
Co-authored-by: liqun Fu 
Co-authored-by: Baiju Meswani 
Co-authored-by: Tianlei Wu 
Co-authored-by: Chen Fu 
Co-authored-by: Ye Wang 
Co-authored-by: cao lei 
Co-authored-by: Yufeng Li 
Co-authored-by: Rachel Guo 
Co-authored-by: Patrice Vignola
2023-05-19 14:04:43 -07:00

370 lines
10 KiB
JavaScript

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
'use strict';
const path = require('path');
const webpack = require('webpack');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");
const minimist = require('minimist');
// commandline args
const args = minimist(process.argv);
const bundleMode = args['bundle-mode'] || 'prod'; // 'prod'|'dev'|'perf'|'node'|undefined;
const useAnalyzer = !!args.a || !!args['use-analyzer']; // -a, --use-analyzer
const filter = args.f || args.filter;
const VERSION = require(path.join(__dirname, 'package.json')).version;
const COPYRIGHT_BANNER = `/*!
* ONNX Runtime Web v${VERSION}
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/`;
function terserEcmaVersionFromWebpackTarget(target) {
switch (target) {
case 'es5':
return 5;
case 'es6':
case 'es2015':
return 2015;
case 'es2017':
return 2017;
default:
throw new RangeError(`not supported ECMA version: ${target}`);
}
}
function defaultTerserPluginOptions(target) {
return {
extractComments: false,
terserOptions: {
ecma: terserEcmaVersionFromWebpackTarget(target),
format: {
comments: false,
},
compress: {
passes: 2
},
mangle: {
reserved: ["_scriptDir","startWorker"]
}
}
};
}
const DEFAULT_BUILD_DEFS = {
DISABLE_WEBGL: false,
DISABLE_WEBGPU: true,
DISABLE_WASM: false,
DISABLE_WASM_PROXY: false,
DISABLE_WASM_THREAD: false,
};
// common config for release bundle
function buildConfig({ filename, format, target, mode, devtool, build_defs }) {
const config = {
target: [format === 'commonjs' ? 'node' : 'web', target],
entry: path.resolve(__dirname, 'lib/index.ts'),
output: {
path: path.resolve(__dirname, 'dist'),
filename,
library: {
type: format
}
},
resolve: {
extensions: ['.ts', '.js'],
alias: {
"util": false,
},
fallback: {
"crypto": false,
"fs": false,
"path": false,
"util": false,
"os": false,
"worker_threads": false,
"perf_hooks": false,
}
},
plugins: [
new webpack.DefinePlugin({ BUILD_DEFS: build_defs }),
new webpack.WatchIgnorePlugin({ paths: [/\.js$/, /\.d\.ts$/] })
],
module: {
rules: [{
test: /\.ts$/,
use: [
{
loader: 'ts-loader',
options: {
compilerOptions: { target }
}
}
]
}, {
test: /ort-wasm.*\.worker\.js$/,
type: 'asset/source'
}]
},
mode,
devtool
};
if (useAnalyzer) {
config.plugins.unshift(new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: `${filename}.report.html`
}));
}
if (mode === 'production') {
config.resolve.alias['./binding/ort-wasm-threaded.js'] = './binding/ort-wasm-threaded.min.js';
config.resolve.alias['./binding/ort-wasm-threaded-simd.jsep.js'] = './binding/ort-wasm-threaded-simd.jsep.min.js';
config.resolve.alias['./binding/ort-wasm-threaded.worker.js'] = './binding/ort-wasm-threaded.min.worker.js';
const options = defaultTerserPluginOptions(target);
options.terserOptions.format.preamble = COPYRIGHT_BANNER;
config.plugins.push(new TerserPlugin(options));
// add a custom plugin to check whether code contains 'BUILD_DEFS'
config.plugins.push({
apply: (compiler) => {
compiler.hooks.afterCompile.tap(
'Check BUILD_DEFS',
(compilation) => {
for (const filename of compilation.assetsInfo.keys()) {
if (filename.endsWith('.js')) {
const asset = compilation.assets[filename];
if (asset) {
const content = asset.source();
if (typeof content !== 'string') {
throw new Error(`content for target file '${filename}' is not string.`);
}
if (content.includes('DISABLE_WEBGL')
|| content.includes('DISABLE_WASM')
|| content.includes('DISABLE_WASM_PROXY')
|| content.includes('DISABLE_WASM_THREAD')) {
throw new Error(`target file '${filename}' contains data fields from "BUILD_DEFS".`);
}
}
}
}
});
}
});
} else {
config.plugins.push(new webpack.BannerPlugin({ banner: COPYRIGHT_BANNER, raw: true }));
}
return config;
}
// "ort{.min}.js" config
function buildOrtConfig({
suffix = '',
target = 'es2017',
mode = 'production',
devtool = 'source-map',
build_defs = DEFAULT_BUILD_DEFS
}) {
const config = buildConfig({ filename: `ort${suffix}.js`, format: 'umd', target, mode, devtool, build_defs });
// set global name 'ort'
config.output.library.name = 'ort';
return config;
}
// "ort-web{.min|.node}.js" config
function buildOrtWebConfig({
suffix = '',
format = 'umd',
target = 'es2017',
mode = 'production',
devtool = 'source-map',
build_defs = DEFAULT_BUILD_DEFS
}) {
const config = buildConfig({ filename: `ort-web${suffix}.js`, format, target, mode, devtool, build_defs });
// exclude onnxruntime-common from bundle
config.externals = {
'onnxruntime-common': {
commonjs: "onnxruntime-common",
commonjs2: "onnxruntime-common",
root: 'ort'
}
};
// in nodejs, treat as external dependencies
if (format === 'commonjs') {
config.externals.path = 'path';
config.externals.fs = 'fs';
config.externals.util = 'util';
config.externals.worker_threads = 'worker_threads';
config.externals.perf_hooks = 'perf_hooks';
config.externals.os = 'os';
}
return config;
}
function buildTestRunnerConfig({
suffix = '',
format = 'umd',
target = 'es2017',
mode = 'production',
devtool = 'source-map',
build_defs = DEFAULT_BUILD_DEFS
}) {
const config = {
target: ['web', target],
entry: path.resolve(__dirname, 'test/test-main.ts'),
output: {
path: path.resolve(__dirname, 'test'),
filename: `ort${suffix}.js`,
library: {
type: format
},
devtoolNamespace: '',
},
externals: {
'onnxruntime-common': 'ort',
'fs': 'fs',
'perf_hooks': 'perf_hooks',
'worker_threads': 'worker_threads',
'../../node': '../../node'
},
resolve: {
alias: {
// make sure to refer to original source files instead of generated bundle in test-main.
'..$': '../lib/index'
},
extensions: ['.ts', '.js'],
fallback: {
'./binding/ort-wasm.js': false,
'./binding/ort-wasm-threaded.js': false,
'./binding/ort-wasm-threaded.worker.js': false
}
},
plugins: [
new webpack.DefinePlugin({ BUILD_DEFS: build_defs }),
new webpack.WatchIgnorePlugin({ paths: [/\.js$/, /\.d\.ts$/] }),
new NodePolyfillPlugin({
excludeAliases: ["console", "Buffer"]
}),
],
module: {
rules: [{
test: /\.ts$/,
use: [
{
loader: 'ts-loader',
options: {
compilerOptions: { target }
}
}
]
}, {
test: /ort-wasm.*\.worker\.js$/,
type: 'asset/source'
}]
},
mode: mode,
devtool: devtool,
};
if (mode === 'production') {
config.plugins.push(new TerserPlugin(defaultTerserPluginOptions(target)));
}
return config;
}
module.exports = () => {
const builds = [];
switch (bundleMode) {
case 'prod':
builds.push(
// ort.min.js
buildOrtConfig({ suffix: '.min' }),
// ort.js
buildOrtConfig({ mode: 'development', devtool: 'inline-source-map' }),
// ort.es6.min.js
buildOrtConfig({ suffix: '.es6.min', target: 'es6' }),
// ort.es5.min.js
buildOrtConfig({ suffix: '.es5.min', target: 'es5' }),
// ort.wasm.min.js
buildOrtConfig({
suffix: '.wasm.min', build_defs: {
...DEFAULT_BUILD_DEFS,
DISABLE_WEBGL: true,
}
}),
// ort.webgl.min.js
buildOrtConfig({
suffix: '.webgl.min', build_defs: {
...DEFAULT_BUILD_DEFS,
DISABLE_WASM: true,
}
}),
// ort.wasm-core.min.js
buildOrtConfig({
suffix: '.wasm-core.min', build_defs: {
...DEFAULT_BUILD_DEFS,
DISABLE_WEBGL: true,
DISABLE_WASM_PROXY: true,
DISABLE_WASM_THREAD: true,
}
}),
// ort.webgpu.min.js
buildOrtConfig({
suffix: '.webgpu.min', build_defs: {
...DEFAULT_BUILD_DEFS,
DISABLE_WEBGPU: false,
}
}),
// ort-web.min.js
buildOrtWebConfig({ suffix: '.min' }),
// ort-web.js
buildOrtWebConfig({ mode: 'development', devtool: 'inline-source-map' }),
// ort-web.es6.min.js
buildOrtWebConfig({ suffix: '.es6.min', target: 'es6' }),
// ort-web.es5.min.js
buildOrtWebConfig({ suffix: '.es5.min', target: 'es5' }),
);
case 'node':
builds.push(
// ort-web.node.js
buildOrtWebConfig({ suffix: '.node', format: 'commonjs' }),
);
break;
case 'dev':
builds.push(buildTestRunnerConfig({
suffix: '.dev', mode: 'development', devtool: 'inline-source-map', build_defs: {
...DEFAULT_BUILD_DEFS,
DISABLE_WEBGPU: false,
}
}));
break;
case 'perf':
builds.push(buildTestRunnerConfig({
suffix: '.perf', build_defs: {
...DEFAULT_BUILD_DEFS,
DISABLE_WEBGPU: false,
}
}));
break;
default:
throw new Error(`unsupported bundle mode: ${bundleMode}`);
}
if (filter) {
const filterRegex = new RegExp(filter);
return builds.filter(b => filterRegex.test(b.output.filename));
}
return builds;
};