question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Automatic publicPath is not supported in this browser

See original GitHub issue

I’m getting the follow issues during our pipeline build after doing an upgrade.

Automatic publicPath is not supported in this browser
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';

Here is my webpack config:

// https://developers.google.com/web/tools/workbox/guides/codelabs/webpack
// ~~ WebPack
const path = require('path');
const merge = require('webpack-merge');
const webpack = require('webpack');
const webpackBase = require('./../../../.webpack/webpack.base.js');
// ~~ Plugins
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
  .BundleAnalyzerPlugin;
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractCssChunksPlugin = require('extract-css-chunks-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { InjectManifest } = require('workbox-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const GoogleFontsPlugin = require('@beyonk/google-fonts-webpack-plugin');
const ZipPlugin = require('zip-webpack-plugin');
// ~~ Rules
const extractStyleChunksRule = require('./rules/extractStyleChunks.js');
const replaceEnvVars = require('./replaceEnvVars.js');
// ~~ Build Type
const isProdBuild = process.env.NODE_ENV === 'production';
const isOnlineBuild = process.env.SS_BUILD_TYPE !== 'offline';
// ~~ Directories
const SRC_DIR = path.join(__dirname, '../src');
const PUBLIC_DIR = path.join(__dirname, '../public');
const CompressionPlugin = require('compression-webpack-plugin');
const DIST_DIR = path.join(__dirname, isOnlineBuild ? '../dist' : '../offline');
// ~~ Env Vars
const HTML_TEMPLATE = process.env.HTML_TEMPLATE || 'index.html';
const PUBLIC_URL = isOnlineBuild ? process.env.SS_APP_PUBLIC_URL || '/' : '';
const APP_CONFIG = process.env.APP_CONFIG || 'config/default.js';
const PROXY_TARGET = process.env.PROXY_TARGET;
const PROXY_DOMAIN = process.env.PROXY_DOMAIN;
const HOST_NAME = process.env.SS_APP_HOST_NAME || 'http://localhost';
const HOST_PORT = process.env.SS_APP_ROOT_PORT || 3000;

let SERVER_HOST = `${HOST_NAME}:${HOST_PORT}${PUBLIC_URL}`;
SERVER_HOST = SERVER_HOST.replace(/\/$/, ''); // ensure it does not end with /

const ENTRY_TARGET = process.env.ENTRY_TARGET || `${SRC_DIR}/index.js`;

const onProxyReqCors = (proxyReq, req, res) => {
  const method = req.method.toLowerCase();
  if (method === 'options') {
    // By-pass browser pre-flight options
    // Chrome sends `OPTIONS` header before making an actual request for
    // certain CORS requests (e.g. running on a port differnt than 80/443)
    // intercepting the traffic and sending an OK status allows the browser
    // to not panic about the OPTION request and send the real request.
    res.writeHead(200, req.headers);
    res.write(
      'Option Request was Successful!' +
        '\n' +
        JSON.stringify(req.headers, true, 2)
    );

    res.end();
  } else {
    proxyReq.headers = proxyReq.headers || {};
    proxyReq.headers['Access-Control-Allow-Origin'] = '*';
    proxyReq.headers['mode'] = 'no-cors';
  }
};

// @TODO Use onProxyReqCors
const setHeaders = (res, path) => {
  res.setHeader('Content-Type', 'text/plain');
  if (path.indexOf('.gz') !== -1) {
    res.setHeader('Content-Encoding', 'gzip');
  } else if (path.indexOf('.br') !== -1) {
    res.setHeader('Content-Encoding', 'br');
  }
};

module.exports = (env, argv) => {
  const baseConfig = webpackBase(env, argv, { SRC_DIR, DIST_DIR });
  const hasProxy = PROXY_TARGET && PROXY_DOMAIN;

  const mergedConfig = merge(baseConfig, {
    entry: {
      app: ENTRY_TARGET,
    },
    output: {
      path: DIST_DIR,
      filename: isProdBuild ? '[name].bundle.[chunkhash].js' : '[name].js',
      publicPath: PUBLIC_URL, // Used by HtmlWebPackPlugin for asset prefix
      devtoolModuleFilenameTemplate: function(info) {
        if (isProdBuild) {
          return `webpack:///${info.resourcePath}`;
        } else {
          return 'file:///' + encodeURI(info.absoluteResourcePath);
        }
      },
    },
    resolve: {
      // We use this alias and the CopyPlugin below to support using the dynamic-import version
      // of WADO Image Loader, but only when building a PWA. When we build a package, we must use the
      // bundled version of WADO Image Loader so we can produce a single file for the viewer.
      // (Note: script-tag version of the viewer will no longer be supported in OHIF v3)
      alias: {
        // 'cornerstone-wado-image-loader':
        //   'cornerstone-wado-image-loader/dist/dynamic-import/cornerstoneWADOImageLoader.min.js',
        'cornerstone-wado-image-loader':
          'cornerstone-wado-image-loader/dist/cornerstoneWADOImageLoader.min.js',
      },
    },
    module: {
      rules: [...extractStyleChunksRule(isProdBuild)],
    },
    plugins: [
      // Uncomment to generate bundle analyzer
      // new BundleAnalyzerPlugin(),
      // Clean output.path
      new CleanWebpackPlugin(),
      // Copy "Public" Folder to Dist
      new CompressionPlugin(),
      new CopyWebpackPlugin([
        {
          from: PUBLIC_DIR,
          to: DIST_DIR,
          toType: 'dir',
          // Ignore our HtmlWebpackPlugin template file
          // Ignore our configuration files
          ignore: ['config/*', 'html-templates/*', '.DS_Store'],
        },
        // Short term solution to make sure GCloud config is available in output
        // for our docker implementation
        {
          from: `${PUBLIC_DIR}/config/google.js`,
          to: `${DIST_DIR}/google.js`,
        },
        {
          from: `${PUBLIC_DIR}/.htaccess`,
          to: `${DIST_DIR}/`,
        },
        // Copy over and rename our target app config file
        {
          from: `${PUBLIC_DIR}/${APP_CONFIG}`,
          to: `${DIST_DIR}/app-config.js`,
          transform(content) {
            return replaceEnvVars(content, process.env);
          },
        },
        {
          from:
            '../../../node_modules/cornerstone-wado-image-loader/dist/dynamic-import',
          to: DIST_DIR,
        },
      ]),
      // https://github.com/faceyspacey/extract-css-chunks-webpack-plugin#webpack-4-standalone-installation
      new ExtractCssChunksPlugin({
        filename:
          isProdBuild && isOnlineBuild ? '[name].[hash].css' : '[name].css',
        chunkFilename:
          isProdBuild && isOnlineBuild ? '[id].[hash].css' : '[id].css',
        ignoreOrder: false, // Enable to remove warnings about conflicting order
      }),
      // Generate "index.html" w/ correct includes/imports
      new HtmlWebpackPlugin({
        template: `${PUBLIC_DIR}/html-templates/${HTML_TEMPLATE}`,
        filename: 'index.html',
        templateParameters: {
          PUBLIC_URL: PUBLIC_URL,
        },
      }),
      // No longer maintained; but good for generating icons + manifest
      // new FaviconsWebpackPlugin( path.join(PUBLIC_DIR, 'assets', 'icons-512.png')),
      new InjectManifest({
        swDest: 'sw.js',
        swSrc: path.join(SRC_DIR, 'service-worker.js'),
        // Increase the limit to 4mb:
        // maximumFileSizeToCacheInBytes: 4 * 1024 * 1024
      }),
      // Bundle with Google Web Fonts
      new GoogleFontsPlugin({
        //apiUrl: 'https://n8n-google-fonts-helper.herokuapp.com/api/fonts',
        fonts: [
          { family: 'Roboto', variants: ['100', '300', '400', '500', '700'] },
        ],
      }),
    ],
    optimization: {
      splitChunks: {
        // include all types of chunks
        chunks: 'all',
      },
      //runtimeChunk: 'single',
      minimize: isProdBuild,
      sideEffects: true,
    },
    // https://webpack.js.org/configuration/dev-server/
    devServer: {
      // gzip compression of everything served
      // Causes Cypress: `wait-on` issue in CI
      // compress: true,
      // http2: true,
      // https: true,
      /*
      before(app) {
        app.use((req, res, next) => {
          res.header('Cross-Origin-Opener-Policy', 'same-origin');
          res.header('Cross-Origin-Embedder-Policy', 'require-corp');
          next();
        });
      },*/
      hot: true,
      //open: true,
      port: HOST_PORT,
      host: 'localhost',
      open: ['/imageviewer/'],
      client: {
        overlay: { errors: true, warnings: false },
      },
      static: [
        {
          directory: path.join(require('os').homedir(), 'dicomweb'),
          staticOptions: {
            extensions: ['gz', 'br'],
            index: 'index.json.gz',
            redirect: true,
            setHeaders,
          },
          publicPath: '/dicomweb',
        },
        {
          directory: '../../testdata',
          staticOptions: {
            extensions: ['gz', 'br'],
            index: 'index.json.gz',
            redirect: true,
            setHeaders,
          },
          publicPath: '/testdata',
        },
      ],
      //publicPath: 'https://localhost:3000/imageviewer/',
      //writeToDisk: true,
      historyApiFallback: {
        disableDotRule: true,
        index: PUBLIC_URL + 'index.html',
      },
      headers: {
        'Cross-Origin-Embedder-Policy': 'require-corp',
        'Cross-Origin-Opener-Policy': 'same-origin',
      },
      proxy: {
        '/wado': {
          target: `https://${PROXY_DOMAIN}/orthanc`,
          changeOrigin: true,
          secure: false,
          onProxyReq: onProxyReqCors,
        },
        '/dicom-web': {
          target: `https://${PROXY_DOMAIN}/orthanc`,
          changeOrigin: true,
          secure: false,
          onProxyReq: onProxyReqCors,
        },
        '/api': {
          target: `https://${PROXY_DOMAIN}`,
          changeOrigin: true,
          secure: true,
          onProxyReq: onProxyReqCors,
        },

        '/broadcasting': {
          target: `https://${PROXY_DOMAIN}`,
          changeOrigin: true,
          secure: true,
          onProxyReq: onProxyReqCors,
        },
      },
    },
    devtool: 'inline-source-map',
  });

  if (hasProxy) {
    mergedConfig.devServer.proxy = {};
    mergedConfig.devServer.proxy[PROXY_TARGET] = PROXY_DOMAIN;
  }

  if (isProdBuild) {
    mergedConfig.optimization.minimizer.push(new OptimizeCSSAssetsPlugin({}));
  }

  if (isProdBuild && !isOnlineBuild) {
    mergedConfig.plugins.push(
      new ZipPlugin({
        path: '../dist',
        filename: 'ivis.zip',
        pathPrefix: 'IVIS',
      })
    );
  }

  if (!isProdBuild) {
    mergedConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
  }

  return mergedConfig;
};

Any suggestions or advice would be appreciated. Thanks

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:1
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
despritcommented, Jun 15, 2022

@Zaid-Safadi

Thank you, I was able to do that in “vitest” in “jsdom” environment with the following:

const script = global.document.createElement("script");
script.setAttribute("src", "/");
Object.defineProperty(global.document, "currentScript", {
  value: script
});

update: same for the Cypress

1reaction
Zaid-Safadicommented, Jun 12, 2022

I don’t think this is something caused by an update to cornerstoneWADOImageLoader but more to the updated versions of the webpack/jest…

The way I solved this is by using the library https://github.com/jsdom/jsdom as a dev dependency to provide the required DOM objects

What you will need is on startup/init of your unit-test library (e.g. jest)

  1. create the document and window objects and assign them to global
  2. Define a “currentScript” property on your document object and set the src value to ‘/’
  3. Define TextEncoder/TextDecoder properties on the window object as these are missing from JSDOM: https://github.com/jsdom/jsdom/issues/2524
  4. For JEST, In your unit test file, use jsdom jest environment /** ** @jest-environment jsdom */
Read more comments on GitHub >

github_iconTop Results From Across the Web

Webpack5 Automatic publicPath is not supported in this browser
The error is caused by a bug in mini-css-extract-plugin 1.3.8 and lower in combination with Webpack 5. It is triggered when a stylesheet ......
Read more >
Uncaught Error: Automatic publicPath is not ... - GitHub
Current Behavior Newly created application using the react preset randomly fails to load in Firefox Steps to Reproduce npx ...
Read more >
Automatic publicPath is not supported in this browser - sage
The error shows in the chrome inspect and it says Automatic publicPath is not supported in this browser. But when I remove my...
Read more >
Webpack5 Automatic publicPath is not supported in this browser
CSS : Webpack5 Automatic publicPath is not supported in this browser [ Beautify Your Computer : https://www.hows.tech/p/recommended.html ] ...
Read more >
Webpack5 Automatic publicPath is not supported in this browser
JavaScript : Webpack5 Automatic publicPath is not supported in this browser [ Gift : Animated Search Engine : https://bit.ly/AnimSearch ] ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found