Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -413,26 +413,40 @@ If you are developing features or fixing bugs that require changes in both Slim
3. **Link dicom-microscopy-viewer in Slim**
In the root directory of your Slim project, run:
```sh
pnpm link --global dicom-microscopy-viewer
pnpm link dicom-microscopy-viewer
```
Do **not** run `pnpm link dicom-microscopy-viewer` inside the `dicom-microscopy-viewer` repo itself — only `pnpm link --global` belongs there.

Verify the link points at your local clone (not the registry copy under `.pnpm`):
```sh
node -e "console.log(require('fs').realpathSync('node_modules/dicom-microscopy-viewer'))"
```

4. **Enable live rebuilding in dicom-microscopy-viewer**
To automatically rebuild `dicom-microscopy-viewer` when you make changes, run the following command in the `dicom-microscopy-viewer` directory:
In a separate terminal, in the `dicom-microscopy-viewer` directory, run:
```sh
pnpm run webpack:dynamic-import:watch
```
This will watch for file changes and rebuild the library, so Slim can immediately use the updated code.
Slim imports the **built** `dist/dynamic-import` bundle, not `src/` directly. Wait for DMV watch to report `[emitted] dicomMicroscopyViewer.min.js` after each change.

5. **Run Slim as usual**
In the Slim directory, start the development server:
```sh
pnpm run start
```
Slim will now use your locally linked version of `dicom-microscopy-viewer`.
When linked, `craco.config.js` registers the DMV `dist/` folder as a webpack watch dependency so Slim rebuilds after DMV watch emits a new bundle. Restart Slim after linking or after changing `craco.config.js`.

### Notes

- If you want to unlink and return to the npm-published version, run `pnpm unlink --global dicom-microscopy-viewer` and `pnpm install` in the Slim directory.
- Running `pnpm install` in Slim removes the link — re-run step 3 afterward.
- Do not add `link:` overrides to `package.json`; the commands above are sufficient.
- Slim imports OpenLayers CSS directly (`ol/ol.css`), so `ol` is listed as a direct dependency. This keeps linked dev working when DMV's transitive dependencies are not hoisted into Slim's `node_modules`.
- If Slim still serves a stale DMV bundle, confirm step 3 (realpath must not contain `.pnpm`) and that DMV watch logged `[emitted] dicomMicroscopyViewer.min.js` for your change.
- To unlink and return to the npm-published version:
```sh
pnpm unlink dicom-microscopy-viewer
pnpm install
```

## Citation

Expand Down
78 changes: 75 additions & 3 deletions craco.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
const fs = require('fs')

Check warning on line 1 in craco.config.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `node:fs` over `fs`.

See more on https://sonarcloud.io/project/issues?id=ImagingDataCommons_slim&issues=AZ6YTo_rWY_hOOBLtmT6&open=AZ6YTo_rWY_hOOBLtmT6&pullRequest=389
const path = require('path')

Check warning on line 2 in craco.config.js

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `node:path` over `path`.

See more on https://sonarcloud.io/project/issues?id=ImagingDataCommons_slim&issues=AZ6YTo_rWY_hOOBLtmT7&open=AZ6YTo_rWY_hOOBLtmT7&pullRequest=389
const CracoLessPlugin = require('craco-less')
const CopyWebpackPlugin = require('copy-webpack-plugin')

/**
* When dicom-microscopy-viewer is pnpm-linked, resolve the real repo path so
* webpack can watch DMV dist/ rebuilds. The import alias must stay under
* node_modules (CRA ModuleScopePlugin blocks absolute paths outside src/).
*/
function getLinkedDmvPaths() {
const dmvEntry = path.resolve(
__dirname,
'node_modules/dicom-microscopy-viewer',
)
let dmvRoot
try {
dmvRoot = fs.realpathSync(dmvEntry)
} catch {
return null
}

const isLinked = !dmvRoot.includes(`${path.sep}.pnpm${path.sep}`)
if (!isLinked) {
return null
}

const dmvDist = path.join(dmvRoot, 'dist/dynamic-import')
const dmvBundle = path.join(dmvDist, 'dicomMicroscopyViewer.min.js')
return { dmvRoot, dmvDist, dmvBundle }
}

module.exports = {
plugins: [
{
Expand All @@ -26,8 +55,17 @@
],
webpack: {
configure: (config, { env, paths }) => {
const linkedDmv =
env === 'development' ? getLinkedDmvPaths() : null
const dmvDist =
'./node_modules/dicom-microscopy-viewer/dist/dynamic-import'
const dmvAlias =
'dicom-microscopy-viewer/dist/dynamic-import/dicomMicroscopyViewer.min.js'

config.resolve = {
...config.resolve,
fallback: {
...config.resolve?.fallback,
fs: false,
path: false
},
Expand All @@ -39,16 +77,16 @@
* for the viewer.
*/
alias: {
'dicom-microscopy-viewer':
'dicom-microscopy-viewer/dist/dynamic-import/dicomMicroscopyViewer.min.js'
...config.resolve?.alias,
'dicom-microscopy-viewer': dmvAlias
}
}
config.plugins.push(
// TO DO: remove hard coded path
new CopyWebpackPlugin({
patterns: [
{
from: './node_modules/dicom-microscopy-viewer/dist/dynamic-import',
from: dmvDist,
to: './static/js'
}
]
Expand All @@ -58,6 +96,40 @@
config.experiments = {
asyncWebAssembly: true
}

if (linkedDmv) {
config.watchOptions = {
...config.watchOptions,
followSymlinks: true,
}

config.snapshot = {
...config.snapshot,
managedPaths: [
/^(.+?[\\/]node_modules[\\/])(?!dicom-microscopy-viewer)/,
],
}

config.plugins.push({
apply: (compiler) => {
compiler.hooks.afterCompile.tap('WatchLinkedDmvDist', (compilation) => {
compilation.contextDependencies.add(linkedDmv.dmvDist)
compilation.fileDependencies.add(linkedDmv.dmvBundle)
})
},
})

config.devServer = {
...config.devServer,
watchFiles: {
paths: [`${linkedDmv.dmvDist}/**/*`],
options: {
followSymlinks: true,
},
},
}
}

return config
}
},
Expand Down
1 change: 0 additions & 1 deletion src/components/SlideViewer/utils/viewerUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export const constructViewers = ({
clientMapping: clients,
metadata: slide.volumeImages,
controls: ['overview', 'position'],
skipThumbnails: true,
preload,
annotationOptions:
clusteringPixelSizeThreshold !== undefined
Expand Down
Loading