itk-vtk-viewer icon indicating copy to clipboard operation
itk-vtk-viewer copied to clipboard

Importing workers with webpack.

Open phcerdan opened this issue 4 years ago • 4 comments

I had problems loading the workers:

Loading Worker from “http://localhost:8080/itk/WebWorkers/ImageIO.worker.js” was blocked because of a disallowed MIME type (“text/html”).

Following docs from itkjs, the following works using npm install --save-dev copy-webpack-plugin


const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
  // ...
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.join(__dirname, 'node_modules', 'itk-vtk-viewer', 'dist', 'itk'),
          to: path.join(__dirname, "dist", 'itk')
        },
      ]
    }),
  ],
  // To work with webpack-dev-server:
  devServer: {
    writeToDisk: true,
  },
  // ...

Not sure if this is the standard way of doing it, reporting here just in case it's worth to document, or if there is another solution.

phcerdan avatar Feb 28 '21 12:02 phcerdan

@phcerdan thanks for the note!

Did you observe this requirement when building itk-vtk-viewer, or building a project that uses itk-vtk-viewer as a node dependency?

thewtex avatar Mar 02 '21 16:03 thewtex

The later:

building a project that uses itk-vtk-viewer as a node dependency

phcerdan avatar Mar 03 '21 08:03 phcerdan

We should add documentation for how to use itk-vtk-viewer as a dependency.

@jourdain also has a few good ideas/examples on how to use webpack-chain.

thewtex avatar Mar 09 '21 18:03 thewtex

Ideally we should have the following files inside each project so we can import and use them directly

(Caution: Some path resolution will be wrong if those files get placed in their repo)

itkChain.js

const path = require('path');

const root  = path.resolve(__dirname, '..');
const pathsToCopy = [
  {
    from: path.join(root, 'node_modules', 'itk', 'WebWorkers'),
    to: path.join(root, 'dist', 'itk', 'WebWorkers'),
  },
  {
    from: path.join(root, 'node_modules', 'itk', 'ImageIOs'),
    to: path.join(root, 'dist', 'itk', 'ImageIOs'),
  },
  {
    from: path.join(root, 'node_modules', 'itk', 'MeshIOs'),
    to: path.join(root, 'dist', 'itk', 'MeshIOs'),
  },
  {
    from: path.join(root, 'node_modules', 'itk', 'PolyDataIOs'),
    to: path.join(root, 'dist', 'itk', 'PolyDataIOs'),
  },
  {
    from: path.join(root, 'node_modules', 'itk', 'Pipelines'),
    to: path.join(root, 'dist', 'itk', 'Pipelines'),
  },
  {
    from: path.join(
      root,
      'node_modules', 'itk-vtk-viewer',
      'src',
      'Compression',
      'blosc-zarr',
      'web-build'
    ),
    to: path.join(root, 'dist', 'itk', 'Pipelines'),
  },
  {
    from: path.join(root, 'node_modules', 'itk-vtk-viewer', 'src', 'IO', 'Downsample', 'web-build'),
    to: path.join(root, 'dist', 'itk', 'Pipelines'),
  },
];

module.exports = function chainWebpack(config) {
  config
    .plugin('copy')
    .tap(args => {
      for (let i = 0; i < pathsToCopy.length; i++) {
        args[0].push(pathsToCopy[i]);
      }
      return args;
    });
}

itkVtkViewerChain.js

module.exports = function chainWebpack(config) {
  config.module
    .rule('itk-viewer-js')
    .test(/\.js$/i)
    .include.add(/itk-vtk-viewer[/\\]src/)
    .end()
    .use('babel-loader')
    .loader('babel-loader')
    .end();

  config.module
    .rule('itk-viewer-worker')
    .test(/\.worker\.js$/)
    .include.add(/itk-vtk-viewer[/\\]src/)
    .end()
    .use('worker-loader')
    .loader('worker-loader')
    .options({ inline: true })
    .end();
}

I don't remember why I did not used the one in vtk.js/Utilities/config/chainWebpack

vtkChain.js

module.exports = function chainWebpack(config) {
  config.module
    .rule('vtk-glsl')
    .test(/\.glsl$/i)
    .include.add(/vtk\.js[/\\]Sources/)
    .end()
    .use('shader-loader')
    .loader('shader-loader')
    .end();

  config.module
    .rule('vtk-js')
    .test(/\.js$/i)
    .include.add(/vtk\.js[/\\]Sources/)
    .end()
    .use('babel-loader')
    .loader('babel-loader')
    .end();

  config.module
    .rule('vtk-worker')
    .test(/\.worker\.js$/)
    .include.add(/vtk\.js[/\\]Sources/)
    .end()
    .use('worker-loader')
    .loader('worker-loader')
    .options({ inline: true })
    .end();

  config.module
    .rule('vtk-css')
    .test(/\.css$/)
    .exclude.add(/\.module\.css$/)
    .end()
    .include.add(/vtk\.js[/\\]Sources/)
    .end()
    .use('styles')
    .loader('style-loader')
    .loader('css-loader')
    .loader('postcss-loader')
    .end();

  config.module
    .rule('vtk-svg')
    .test(/\.svg$/)
    .include.add(/vtk\.js[/\\]Sources/)
    .end()
    .use('raw-loader')
    .loader('raw-loader')
    .end();

  config.module
    .rule('svg')
    .exclude.add(/vtk\.js[/\\]Sources/)
    .end();

  config.module
    .rule('vtk-module-css')
    .test(/\.css$/)
    .include.add(/vtk\.js[/\\]Sources/)
    .add(/\.module\.css$/)
    .end()
    .use('styles')
    .loader('style-loader')
    .loader('css-loader')
    .options({
      modules: {
        localIdentName: '[name]-[local]_[sha512:hash:base64:5]',
      },
    })
    .loader('postcss-loader')
    .end();
}

Then in my vue.config.js

// const vtkChainWebpack = require('vtk.js/Utilities/config/chainWebpack');
const itkViewChainWebpack = require('./config/chainItkVtkViewer');
const itkChainWebpack = require('./config/chainItk');
const vtkChainWebpack = require('./config/chainVTK');

module.exports = {
  chainWebpack: (config) => {
    vtkChainWebpack(config);
    itkViewChainWebpack(config);
    itkChainWebpack(config);
  },
};

jourdain avatar Mar 09 '21 18:03 jourdain