fix: webpack import bugs showing warnings on import (#4265)

This commit is contained in:
Bill Wallace authored and GitHub committed 2024-07-05 13:19:42 -04:00
1 parent 6d11048ca5
commit 24c511f4bc
23 files changed
+975 -1008

No files matched your search

+11 -10
View File
@@ -102,16 +102,17 @@ module.exports = (env, argv) => {
to: `${DIST_DIR}/app-config.js`,
},
// Copy Dicom Microscopy Viewer build files
{
from: '../../../node_modules/dicom-microscopy-viewer/dist/dynamic-import',
to: DIST_DIR,
globOptions: {
ignore: ['**/*.min.js.map'],
},
// The dicom-microscopy-viewer is optional, so if it doeesn't get
// installed, it shouldn't cause issues.
noErrorOnMissing: true,
},
// This is in pluginCOnfig.json now
// {
// from: '../../../node_modules/dicom-microscopy-viewer/dist/dynamic-import',
// to: DIST_DIR,
// globOptions: {
// ignore: ['**/*.min.js.map'],
// },
// // The dicom-microscopy-viewer is optional, so if it doeesn't get
// // installed, it shouldn't cause issues.
// noErrorOnMissing: true,
// },
// Copy dicom-image-loader build files
{
from: '../../../node_modules/@cornerstonejs/dicom-image-loader/dist/dynamic-import',
@@ -66,6 +66,18 @@ function getRuntimeLoadModesExtensions(modules) {
);
modules.forEach(module => {
const packageName = extractName(module);
if (!packageName) {
return;
}
if (module.importPath) {
dynamicLoad.push(
` if( module==="${packageName}") {`,
` const imported = await window.browserImportFunction('${module.importPath}');`,
' return ' + (module.globalName ? `window["${module.globalName}"];` : `imported["${module.importName || 'default'}"];`),
' }'
);
return;
}
dynamicLoad.push(
` if( module==="${packageName}") {`,
` const imported = await import("${packageName}");`,
@@ -73,8 +85,9 @@ function getRuntimeLoadModesExtensions(modules) {
' }'
);
});
// TODO - handle more cases for import than just default
dynamicLoad.push(
' return (await import(/* webpackIgnore: true */ module)).default;',
' return (await window.browserImportFunction(module)).default;',
'}\n',
'// Import a list of items (modules or string names)',
'// @return a Promise evaluating to a list of modules',
@@ -144,6 +157,7 @@ function writePluginImportsFile(SRC_DIR, DIST_DIR) {
pluginImportsJsContent += getRuntimeLoadModesExtensions([
...pluginConfig.extensions,
...pluginConfig.modes,
...pluginConfig.public,
]);
fs.writeFileSync(`${SRC_DIR}/pluginImports.js`, pluginImportsJsContent, { flag: 'w+' }, err => {
+6
View File
@@ -88,6 +88,12 @@
"public": [
{
"directory": "./platform/public"
},
{
"packageName": "dicom-microscopy-viewer",
"importPath": "/dicom-microscopy-viewer/dicomMicroscopyViewer.min.js",
"globalName": "dicomMicroscopyViewer",
"directory": "./node_modules/dicom-microscopy-viewer/dist/dynamic-import"
}
]
}
@@ -210,6 +210,12 @@
rel="preload"
as="style"
/>
<script>
function browserImportFunction(moduleId) {
return import(moduleId);
}
</script>
<!-- EXTENSIONS -->
<!-- <script type="text/javascript" src="path/to/some-extension.js"></script>
+4 -2
View File
@@ -24,7 +24,7 @@ import {
// utils,
} from '@ohif/core';
import loadModules from './pluginImports';
import loadModules, { loadModule as peerImport } from './pluginImports';
/**
* @param {object|func} appConfigOrFunc - application configuration, or a function that returns application configuration
@@ -42,9 +42,11 @@ async function appInit(appConfigOrFunc, defaultExtensions, defaultModes) {
const appConfig = {
...(typeof appConfigOrFunc === 'function'
? await appConfigOrFunc({ servicesManager, loadModules })
? await appConfigOrFunc({ servicesManager, peerImport })
: appConfigOrFunc),
};
// Default the peer import function
appConfig.peerImport ||= peerImport;
const extensionManager = new ExtensionManager({
commandsManager,
+1 -1
View File
@@ -37,7 +37,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.3",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^1.81.6",
"@cornerstonejs/dicom-image-loader": "^1.82.0",
"@ohif/ui": "3.9.0-beta.58",
"cornerstone-math": "0.1.9",
"dicom-parser": "^1.8.21"
@@ -31,6 +31,7 @@ export interface ExtensionParams extends ExtensionConstructor {
servicesManager: AppTypes.ServicesManager;
serviceProvidersManager: ServiceProvidersManager;
configuration?: ExtensionConfiguration;
peerImport: (moduleId: string) => Promise<any>;
}
/**
@@ -88,6 +89,7 @@ export default class ExtensionManager extends PubSubService {
private dataSourceDefs: Record<string, any>;
private defaultDataSourceName: string;
private activeDataSource: string;
private peerImport: (moduleId) => Promise<any>;
constructor({
commandsManager,
@@ -116,6 +118,7 @@ export default class ExtensionManager extends PubSubService {
this.dataSourceDefs = {};
this.defaultDataSourceName = appConfig.defaultDataSourceName;
this.activeDataSource = appConfig.defaultDataSourceName;
this.peerImport = appConfig.peerImport;
}
public setActiveDataSource(dataSource: string): void {
@@ -608,6 +611,10 @@ export default class ExtensionManager extends PubSubService {
);
});
};
public get appConfig() {
return this._appConfig;
}
}
/**
+2 -1
View File
@@ -122,13 +122,14 @@ declare global {
onConfiguration?: (dicomWebConfig: any, options: any) => any;
dataSources?: any;
oidc?: any;
peerImport?: (moduleId: string) => Promise<any>;
studyPrefetcher: {
enabled: boolean;
displaySetsCount: number;
maxNumPrefetchRequests: number;
order: 'closest' | 'downward' | 'upward';
}
}
}
export interface Test {
services?: Services;
@@ -35,6 +35,9 @@ What's Changing?
</Tabs>
### Run newer yarn version
You must be running a newer yarn version for react 18.
It isn't clear the exact yarn required.
### Update React version:
In your custom extensions and modes, change the version of react and react-dom to ^18.3.1.
@@ -160,6 +163,57 @@ To disable it, remove the configuration from the `initToolGroups` in your mode.
<br/>
## External Libraries
Some libraries are loaded via dynamic import. You can provide a global function
`browserImport` the allows loading of dynamic imports without affecting the
webpack build. This import looks like:
```
<script>
function browserImportFunction(moduleId) {
return import(moduleId);
}
</script>
```
and belongs in the root html file for your application.
You then need to remove `dependencies` on the external import, and add a reference
to the external import in your `pluginConfig.json` file.
### Example plugin config for `dicom-microscopy-viewer`
The example below imports the `dicom-microscopy-viewer` for use as an external
dependency. The example is part of the default `pluginConfig.json` file.
```
"public": [
{
"directory": "./platform/public"
},
{
"packageName": "dicom-microscopy-viewer",
"importPath": "/dicom-microscopy-viewer/dicomMicroscopyViewer.min.js",
"globalName": "dicomMicroscopyViewer",
"directory": "./node_modules/dicom-microscopy-viewer/dist/dynamic-import"
}
]
```
This defines two directory modules, whose contents are copied unchanged to the
output build directory. It then defines the `dicom-microscopy-viewer` using
the `packageName` element as being a module which is imported dynamically.
Then, the import path passed into the browserImportFunction above is
specified, and then how to access the import itself, via the `window.dicomMicroscopyViewer`
global name reference.
### Referencing External Imports
The appConfig either defines or has a default peerImport function which can be
used to load references to the modules defined in the pluginConfig file. See
the example in `init.tsx` for the cornerstone extension for how this is passed
into CS3D for loading the whole slide imaging library.
### Usage of Dynamic Imports
## BulkDataURI Configuration
We've updated the configuration for BulkDataURI to provide more flexibility and control. This guide will help you migrate from the old configuration to the new one.
+11
View File
@@ -0,0 +1,11 @@
const path = require('path');
const webpackCommon = require('./../../../.webpack/webpack.base.js');
const SRC_DIR = path.join(__dirname, '../src');
const DIST_DIR = path.join(__dirname, '../dist');
const ENTRY = {
app: `${SRC_DIR}/index.ts`,
};
module.exports = (env, argv) => {
return webpackCommon(env, argv, { SRC_DIR, DIST_DIR, ENTRY });
};
+60
View File
@@ -0,0 +1,60 @@
const { merge } = require('webpack-merge');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const webpackCommon = require('./../../../.webpack/webpack.base.js');
const pkg = require('./../package.json');
const ROOT_DIR = path.join(__dirname, './..');
const SRC_DIR = path.join(__dirname, '../src');
const DIST_DIR = path.join(__dirname, '../dist');
const ENTRY = {
app: `${SRC_DIR}/index.ts`,
};
const outputName = `ohif-${pkg.name.split('/').pop()}`;
module.exports = (env, argv) => {
const commonConfig = webpackCommon(env, argv, { SRC_DIR, DIST_DIR, ENTRY });
return merge(commonConfig, {
stats: {
colors: true,
hash: true,
timings: true,
assets: true,
chunks: false,
chunkModules: false,
modules: false,
children: false,
warnings: true,
},
optimization: {
minimize: true,
sideEffects: false,
},
output: {
path: ROOT_DIR,
library: 'ohif-ui',
libraryTarget: 'umd',
filename: pkg.main,
},
externals: [
/\b(dcmjs)/,
/\b(gl-matrix)/,
{
react: 'React',
'react-dom': 'ReactDOM',
},
],
plugins: [
new MiniCssExtractPlugin({
filename: `./dist/${outputName}.css`,
chunkFilename: `./dist/${outputName}.css`,
}),
// new BundleAnalyzerPlugin({}),
],
});
};
+15 -2
View File
@@ -2,9 +2,22 @@
"name": "@ohif/ui-next",
"version": "3.9.0-beta.58",
"description": "Next version of OHIF Viewers UI, more customizable using shadcn/ui",
"main": "index.ts",
"main": "dist/ohif-ui-next.umd.js",
"module": "src/index.ts",
"publishConfig": {
"access": "public"
},
"files": [
"dist",
"README.md"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"clean": "rm -rf node_modules/.cache/storybook && shx rm -rf dist",
"clean:deep": "yarn run clean && shx rm -rf node_modules",
"start": "yarn run build --watch",
"test": "echo \"Error: no test specified\" && exit 1",
"build": "cross-env NODE_ENV=production webpack --config .webpack/webpack.prod.js",
"build:package": "yarn run build"
},
"exports": {
"./tailwind.config": "./tailwind.config.ts",