fix: measurementsAPI issue caused by production build (#842)

* ci: test docs-publish

* Specify to use prod

* Babel should transpile with env set by webpack

* in-progress

* in-progress

* Polyfill for ie11 and edge features

* Ditch polyfills w/ babel - we'll use a service for now

* Bump tools version; shift vtk.js up a layer

* Specify we shouldn't target older than IE 11

* ditch babel plugins that should be covered by preset-env

* Add a top level build demo command

* Let our babel config determine settings

* Same babel fixes as PWA

* Rebuild deps that don't satisfy our target

* Mini helper script for excluding all node_modules, except...

* Shift vtk.js dep up a layer

* Kill core-js

* Export in a node happy way

* Updated yarn lock

* Set NODE_ENV when launching anything w/ WebPack

* docs: updated FAQ

* docs: on browser support

* Add support for redux browser extension

* misc. small clean-up

* docs: Remove roadmap page; add browser-support to sidebar

* Formatting

* Remove roadmap links

* Formatting

* ci: Remove config syntax error

* Simplified bug report template

* update community request template

* Update question's template

* simplify build scripts

* specify new script names

* fix: for measurement api being pruned by minimizer in prod builds

* Use named exports

* Simplify config

* Let's not do so much heavy lifting for a dev-server build

* fix dev build

* Add hotkeys to demo

* fix: jest babel config and env specific configs

* Remove call to non-existant command

* Shift experimental proposal plugin up a layer

* Use `https`

* Try with reduced number of package exceptions

* Try to resolve cypress issue

* Try to fix cypress issue in CI

* Skip https
This commit is contained in:
Danny Brown authored and GitHub committed 2019-09-04 13:53:13 -04:00
1 parent 25e7232660
commit 49d343941e
63 files changed
+1773 -813

No files matched your search

+7
View File
@@ -0,0 +1,7 @@
# Browsers that we support
> 1%
IE 11
not IE < 11
not dead
not op_mini all
-74
View File
@@ -1,74 +0,0 @@
/**
* Notice that we're not extracting CSS or generating a service-worker. This
* may create a slightly inconsistent experience, but should allow for faster/
* easier development.
*
* We do still need to generate the "index.html" and copy over files from
* "public/" so our `webpack-dev-server` can _serve_ them for us :+1:
*/
const path = require('path');
const merge = require('webpack-merge');
const webpack = require('webpack');
const webpackCommon = require('./../../../.webpack/webpack.common.js');
// Plugins
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// Const
const SRC_DIR = path.join(__dirname, '../src');
const DIST_DIR = path.join(__dirname, '../dist');
const PUBLIC_DIR = path.join(__dirname, '../public');
const ASSET_PATH = process.env.ASSET_PATH || '/';
// Env Vars
const HTML_TEMPLATE = process.env.HTML_TEMPLATE || 'index.html';
const PUBLIC_URL = process.env.PUBLIC_URL || '/';
const APP_CONFIG = process.env.APP_CONFIG || 'config/default.js';
module.exports = (env, argv) => {
const commonConfig = webpackCommon(env, argv, { SRC_DIR, DIST_DIR });
return merge(commonConfig, {
// https://webpack.js.org/configuration/mode/#mode-development
mode: 'development',
output: {
path: DIST_DIR, // push to common?
publicPath: ASSET_PATH,
// filename: '[name].bundle.js',
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
// Copy "Public" Folder to Dist
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'],
},
// Copy over and rename our target app config file
{
from: `${PUBLIC_DIR}/${APP_CONFIG}`,
to: `${DIST_DIR}/app-config.js`,
},
]),
// Generate "index.html" w/ correct includes/imports
new HtmlWebpackPlugin({
template: `${PUBLIC_DIR}/html-templates/${HTML_TEMPLATE}`,
filename: 'index.html',
templateParameters: {
PUBLIC_URL: PUBLIC_URL,
},
}),
],
// https://webpack.js.org/configuration/dev-server/
devServer: {
hot: true,
open: true,
port: 3000,
historyApiFallback: {
disableDotRule: true,
},
},
});
};
@@ -0,0 +1,35 @@
const ExtractCssChunksPlugin = require('extract-css-chunks-webpack-plugin');
function extractStyleChunks(isProdBuild) {
return [
{
test: /\.styl$/,
use: [
{
loader: ExtractCssChunksPlugin.loader,
options: {
hot: !isProdBuild,
},
},
{ loader: 'css-loader' },
{ loader: 'stylus-loader' },
],
},
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: ExtractCssChunksPlugin.loader,
options: {
hot: !isProdBuild,
},
},
'css-loader',
'postcss-loader',
// 'sass-loader',
],
},
];
}
module.exports = extractStyleChunks;
@@ -0,0 +1,20 @@
/**
* For CommonJS, we want to bundle whatever font we've landed on. This allows
* us to reduce the number of script-tags we need to specify for simple use.
*
* PWA will grab these externally to reduce bundle size (think code split),
* and cache the grab using service-worker.
*/
const fontsToJavaScript = {
test: /\.(ttf|eot|woff|woff2)$/i,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
},
},
],
};
module.exports = fontsToJavaScript;
@@ -1,9 +1,9 @@
const path = require('path');
const merge = require('webpack-merge');
const webpack = require('webpack');
const webpackCommon = require('./../../../.webpack/webpack.common.js');
const webpackCommon = require('./../../../.webpack/webpack.commonjs.js');
//
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const fontsToJavaScriptRule = require('./rules/fontsToJavaScript.js');
// const
const SRC_DIR = path.join(__dirname, '../src');
const DIST_DIR = path.join(__dirname, '../dist');
@@ -12,8 +12,6 @@ module.exports = (env, argv) => {
const commonConfig = webpackCommon(env, argv, { SRC_DIR, DIST_DIR });
return merge(commonConfig, {
// https://webpack.js.org/configuration/mode/#mode-production
mode: 'production',
entry: {
bundle: `${SRC_DIR}/index-umd.js`,
},
@@ -39,27 +37,8 @@ module.exports = (env, argv) => {
libraryTarget: 'umd',
filename: 'index.umd.js',
},
/**
* For CommonJS, we want to bundle whatever font we've landed on. This allows
* us to reduce the number of script-tags we need to specify for simple use.
*
* PWA will grab these externally to reduce bundle size (think code split),
* and cache the grab using service-worker.
*/
module: {
rules: [
{
test: /\.(ttf|eot|woff|woff2)$/i,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
},
},
],
},
],
rules: [fontsToJavaScriptRule],
},
plugins: [
// Clean output.path
@@ -1,34 +1,40 @@
// ~~ WebPack
const path = require('path');
const merge = require('webpack-merge');
const webpack = require('webpack');
const webpackCommon = require('./../../../.webpack/webpack.common-pwa.js');
// Plugins
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 WorkboxPlugin = require('workbox-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const workboxPlugin = require('workbox-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
.BundleAnalyzerPlugin;
//
// ~~ Rules
const extractStyleChunksRule = require('./rules/extractStyleChunks.js');
// ~~ Directories
const SRC_DIR = path.join(__dirname, '../src');
const DIST_DIR = path.join(__dirname, '../dist');
const PUBLIC_DIR = path.join(__dirname, '../public');
// Env Vars
// ~~ Env Vars
const HTML_TEMPLATE = process.env.HTML_TEMPLATE || 'index.html';
const PUBLIC_URL = process.env.PUBLIC_URL || '/';
const APP_CONFIG = process.env.APP_CONFIG || 'config/default.js';
module.exports = (env, argv) => {
const commonConfig = webpackCommon(env, argv, { SRC_DIR, DIST_DIR });
const baseConfig = webpackBase(env, argv, { SRC_DIR, DIST_DIR });
const isProdBuild = process.env.NODE_ENV === 'production';
return merge(commonConfig, {
// https://webpack.js.org/configuration/mode/#mode-production
mode: 'production',
// Out of memory -- Code Split
// devtool: 'source-map',
const mergedConfig = merge(baseConfig, {
devtool: isProdBuild ? 'source-map' : 'cheap-module-eval-source-map',
output: {
path: DIST_DIR,
filename: isProdBuild ? '[name].bundle.[chunkhash].js' : '[name].js',
publicPath: PUBLIC_URL, // Used by HtmlWebPackPlugin for asset prefix
},
stats: {
colors: true,
hash: true,
@@ -41,86 +47,31 @@ module.exports = (env, argv) => {
warnings: true,
},
optimization: {
minimize: true,
minimize: isProdBuild,
sideEffects: true,
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
},
output: {
path: DIST_DIR,
filename: '[name].bundle.[chunkhash].js',
publicPath: PUBLIC_URL, // Used by HtmlWebPackPlugin for asset prefix
// // TODO: For more granular minimize
// // minimizer: [
// // new TerserJSPlugin({
// // sourceMap: true,
// // terserOptions: {
// // sourceMap: {
// // file: '[name].map',
// // url: 'https://my-host/[url]',
// // },
// // },
// // }),
// // new OptimizeCSSAssetsPlugin({}),
// // ],
},
module: {
rules: [
{
test: /\.styl$/,
use: [
{
loader: ExtractCssChunksPlugin.loader,
options: {
hot: process.env.NODE_ENV === 'development',
},
},
{ loader: 'css-loader' },
{ loader: 'stylus-loader' },
],
},
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: ExtractCssChunksPlugin.loader,
options: {
hot: process.env.NODE_ENV === 'development',
},
},
'css-loader',
'postcss-loader',
// 'sass-loader',
],
},
],
rules: [...extractStyleChunksRule(isProdBuild)],
},
module: {
rules: [
{
test: /\.styl$/,
use: [
{
loader: ExtractCssChunksPlugin.loader,
options: {
hot: process.env.NODE_ENV === 'development',
},
},
{ loader: 'css-loader' },
{ loader: 'stylus-loader' },
],
},
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: ExtractCssChunksPlugin.loader,
options: {
hot: process.env.NODE_ENV === 'development',
},
},
'css-loader',
'postcss-loader',
// 'sass-loader',
],
},
],
},
// TODO:
// Do we need to rip anything out of the more generic common.js we're
// merging with this?
plugins: [
// Uncomment to generate bundle analyzer
// new BundleAnalyzerPlugin(),
// Clean output.path
new CleanWebpackPlugin(),
// "Public" Folder
// Copy "Public" Folder to Dist
new CopyWebpackPlugin([
{
from: PUBLIC_DIR,
@@ -142,10 +93,7 @@ module.exports = (env, argv) => {
chunkFilename: '[id].css',
ignoreOrder: false, // Enable to remove warnings about conflicting order
}),
/**
* This generates our index.html file from the specified template.
* This is the easiest way to inject custom configuration and extensions.
*/
// Generate "index.html" w/ correct includes/imports
new HtmlWebpackPlugin({
template: `${PUBLIC_DIR}/html-templates/${HTML_TEMPLATE}`,
filename: 'index.html',
@@ -154,11 +102,31 @@ module.exports = (env, argv) => {
},
// favicon: `${PUBLIC_DIR}/favicon.ico`,
}),
new workboxPlugin.GenerateSW({
new WorkboxPlugin.GenerateSW({
swDest: 'sw.js',
clientsClaim: true,
skipWaiting: 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,
hot: true,
open: true,
port: 3000,
historyApiFallback: {
disableDotRule: true,
},
},
});
if (!isProdBuild) {
mergedConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
}
return mergedConfig;
};
+5 -30
View File
@@ -12,7 +12,6 @@
</div>
<div align="center">
<a href="https://docs.ohif.org/demo">Demo</a> |
<a href="https://ohif.canny.io/">Roadmap</a> |
<a href="https://react.ohif.org/">Component Library</a>
</div>
@@ -95,7 +94,9 @@ guide.
### E2E Tests
Using [Cypress](https://www.cypress.io/) to create End-to-End tests and check whether the application flow is performing correctly, ensuring that the integrated components are working as expected.
Using [Cypress](https://www.cypress.io/) to create End-to-End tests and check
whether the application flow is performing correctly, ensuring that the
integrated components are working as expected.
#### Why Cypress?
@@ -146,10 +147,10 @@ When creating tests, place the test file "next to" the file you're testing.
```js
// File
index.js
index.js;
// Test for file
index.test.js
index.test.js;
```
As you add and modify code, `jest` will watch for uncommitted changes and run
@@ -157,32 +158,6 @@ your tests, reporting the results to your terminal. Make a pull request with
your changes to `master`, and a core team member will review your work. If you
have any questions, please don't hesitate to reach out via a GitHub issue.
## Roadmap
If you want to know what's planned for the very near future,
[check out our roadmap](https://ohif.canny.io/). The best way to influence when
and what is worked on is to contribute to the conversation by creating GitHub
issues, and contributing code through pull requests. OHIF's high level
priorities for the near future are:
- Feature parity with version 1
- Extension and configuration improvements with key integration partners
- Continued Developer Experience Improvements
- Segmentation Tools, and improved VTK.js support
More granular information will make it's way to the backlog as these items
become scoped for development by core maintainers.
> Don't hesitate to ask questions, propose features, or create pull requests.
> We're here, we're listening, and we're ready to build the best open source
> medical imaging viewer on the web.
#### Roadmap Generously Powered by Canny.io
<a href="https://ohif.canny.io/">
<img height="30" src="docs/latest/assets/img/canny-full.png" />
</a>
## Contributors
Thanks goes to these wonderful people
+10 -13
View File
@@ -17,13 +17,13 @@
},
"proxy": "http://localhost:8042",
"scripts": {
"build:package": "cross-env NODE_ENV=production node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --config .webpack/commonjs.prod.js",
"build:viewer": "cross-env NODE_ENV=production node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --config .webpack/pwa.prod.js",
"build:viewer:ci": "cross-env NODE_ENV=production PUBLIC_URL=/pwa/ APP_CONFIG=config/netlify.js node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --config .webpack/pwa.prod.js",
"build:viewer:demo": "cross-env NODE_ENV=production APP_CONFIG=config/demo.js HTML_TEMPLATE=rollbar.html node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --config .webpack/pwa.prod.js",
"build:package": "cross-env NODE_ENV=production node --max_old_space_size=8192 ./../../node_modules/webpack/bin/webpack.js --config .webpack/webpack.commonjs.js",
"build:viewer": "cross-env NODE_ENV=production node --max_old_space_size=8192 ./../../node_modules/webpack/bin/webpack.js --config .webpack/webpack.pwa.js",
"build:viewer:ci": "cross-env NODE_ENV=production PUBLIC_URL=/pwa/ APP_CONFIG=config/netlify.js node --max_old_space_size=8192 ./../../node_modules/webpack/bin/webpack.js --config .webpack/webpack.pwa.js",
"build:viewer:demo": "cross-env NODE_ENV=production APP_CONFIG=config/demo.js HTML_TEMPLATE=rollbar.html node --max_old_space_size=8192 ./../../node_modules/webpack/bin/webpack.js --config .webpack/webpack.pwa.js",
"build:viewer:package": "yarn run build:package",
"dev": "webpack-dev-server --config .webpack/all.dev.js -w",
"dev:orthanc": "cross-env APP_CONFIG=config/docker_nginx-orthanc.js react-scripts start",
"dev": "cross-env NODE_ENV=development webpack-dev-server --config .webpack/webpack.pwa.js -w",
"dev:orthanc": "cross-env NODE_ENV=developmen APP_CONFIG=config/docker_nginx-orthanc.js react-scripts start",
"dev:viewer": "yarn run dev",
"start": "yarn run dev",
"orthanc:up": "docker-compose -f docker/Nginx-Orthanc/docker-compose.yml up",
@@ -31,10 +31,6 @@
"test:unit": "jest --watchAll",
"test:unit:ci": "jest --ci --runInBand --collectCoverage"
},
"resolutions": {
"browserslist": "4.6.2",
"caniuse-lite": "1.0.30000974"
},
"files": [
"dist",
"README.md"
@@ -55,10 +51,10 @@
"@ohif/ui": "^0.50.1",
"@tanem/react-nprogress": "^1.1.25",
"classnames": "^2.2.6",
"core-js": "^3.1.4",
"core-js": "^3.2.1",
"cornerstone-core": "^2.2.8",
"cornerstone-math": "^0.1.8",
"cornerstone-tools": "^3.15.1",
"cornerstone-tools": "^3.19.2",
"cornerstone-wado-image-loader": "^3.0.0",
"dcmjs": "^0.4.7",
"dicom-parser": "^1.8.3",
@@ -81,7 +77,8 @@
"redux-logger": "^3.0.6",
"redux-oidc": "3.1.x",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0"
"reselect": "^4.0.0",
"vtk.js": "^11.0.1"
},
"devDependencies": {
"cypress": "^3.3.1",
+46 -3
View File
@@ -1,5 +1,6 @@
window.config = {
routerBasename: '/',
extensions: [],
showStudyList: true,
servers: {
dicomWeb: [
@@ -17,9 +18,51 @@ window.config = {
},
],
},
hotkeys: [
{
commandName: 'incrementActiveViewport',
label: 'Next Image Viewport',
keys: ['right'],
},
{
commandName: 'decrementActiveViewport',
label: 'Previous Image Viewport',
keys: ['left'],
},
{ commandName: 'rotateViewportCW', label: 'Rotate Right', keys: ['r'] },
{ commandName: 'rotateViewportCCW', label: 'Rotate Left', keys: ['l'] },
{ commandName: 'invertViewport', label: 'Invert', keys: ['i'] },
{
commandName: 'flipViewportVertical',
label: 'Flip Horizontally',
keys: ['h'],
},
{
commandName: 'flipViewportHorizontal',
label: 'Flip Vertically',
keys: ['v'],
},
{ commandName: 'scaleUpViewport', label: 'Zoom In', keys: ['+'] },
{ commandName: 'scaleDownViewport', label: 'Zoom Out', keys: ['-'] },
{ commandName: 'fitViewportToWindow', label: 'Zoom to Fit', keys: ['='] },
{ commandName: 'resetViewport', label: 'Reset', keys: ['space'] },
{ commandName: 'nextImage', label: 'Next Image', keys: ['down'] },
{ commandName: 'previousImage', label: 'Previous Image', keys: ['up'] },
{
commandName: 'nextViewportDisplaySet',
label: 'Previous Series',
keys: ['pagedown'],
},
{
commandName: 'previousViewportDisplaySet',
label: 'Next Series',
keys: ['pageup'],
},
{ commandName: 'setZoomTool', label: 'Zoom', keys: ['z'] },
],
i18n: {
LOCIZE_PROJECTID: 'a8da3f9a-e467-4dd6-af33-474d582a0294',
LOCIZE_API_KEY: null, // Developers can use this to do in-context editing. DO NOT COMMIT THIS KEY!
USE_LOCIZE: true
}
}
USE_LOCIZE: true,
},
};
@@ -9,6 +9,9 @@
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="<%= PUBLIC_URL %>manifest.json" />
<!-- Built with: https://polyfill.io/v3/url-builder/ -->
<!-- Targets IE11 -->
<script src="https://polyfill.io/v3/polyfill.min.js?flags=gated&features=default%2CObject.values%2CArray.prototype.flat%2CObject.entries%2CSymbol%2CArray.prototype.includes%2CString.prototype.repeat%2CArray.prototype.find"></script>
<script
type="text/javascript"
src="<%= PUBLIC_URL %>app-config.js"
@@ -9,6 +9,9 @@
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="<%= PUBLIC_URL %>manifest.json" />
<!-- Built with: https://polyfill.io/v3/url-builder/ -->
<!-- Targets IE11 -->
<script src="https://polyfill.io/v3/polyfill.min.js?flags=gated&features=default%2CObject.values%2CArray.prototype.flat%2CObject.entries%2CSymbol%2CArray.prototype.includes%2CString.prototype.repeat%2CArray.prototype.find"></script>
<script type="text/javascript" src="<%= PUBLIC_URL %>app-config.js"></script>
<title>OHIF Viewer</title>
File diff suppressed because it is too large. Load diff
-6
View File
@@ -2,12 +2,6 @@ import { hot } from 'react-hot-loader/root';
import './config';
// Polyfills
// PWA Only?
import 'core-js/features/array/flat';
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import {
CommandsManager,
ExtensionManager,
+3
View File
@@ -2,6 +2,9 @@
* Entry point for development and production PWA builds.
* Packaged (NPM) builds go through `index-umd.js`
*/
import 'regenerator-runtime/runtime';
import App from './App.js';
import React from 'react';
import ReactDOM from 'react-dom';
+4 -5
View File
@@ -2,6 +2,7 @@ import {
applyMiddleware,
combineReducers,
createStore,
compose,
} from 'redux/es/redux.js';
// import { createLogger } from 'redux-logger';
@@ -13,7 +14,8 @@ import thunkMiddleware from 'redux-thunk';
// Combine our ohif-core, ui, and oidc reducers
// Set init data, using values found in localStorage
const { reducers, localStorage } = redux;
// const loggerMiddleware = createLogger();
const middleware = [thunkMiddleware];
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
reducers.ui = layoutReducers;
reducers.oidc = oidcReducer;
@@ -22,10 +24,7 @@ const rootReducer = combineReducers(reducers);
const store = createStore(
rootReducer,
localStorage.loadState(), // preloadedState
applyMiddleware(
thunkMiddleware // Lets us dispatch() functions
// loggerMiddleware // neat middleware that logs actions
)
composeEnhancers(applyMiddleware(...middleware))
);
// When the store's preferences change,