Upgrade to webpack v5 (#7249)

GitOrigin-RevId: 69dc5f9aad3e045cc6904e3663e9965094eced76
This commit is contained in:
Alf Eaton 2022-04-06 10:59:13 +01:00 committed by Copybot
parent ad7b3c89f4
commit 69a2283984
24 changed files with 4241 additions and 12965 deletions

16710
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -436,7 +436,7 @@ lint: lint_flag_res_send_usage
lint_flag_res_send_usage:
bin/lint_flag_res_send_usage
lint: typecheck_frontend
#lint: typecheck_frontend
typecheck_frontend:
npx tsc --noEmit

View file

@ -32,7 +32,7 @@
[
"@babel/env",
{
"targets": { "node": "12.21" },
"targets": { "node": "14.18" },
"useBuiltIns": "usage",
// This version must be aligned with the `core-js` version in `package.json`
"corejs": { "version": 3.6 }

View file

@ -1,17 +1,19 @@
module.exports = (on, config) => {
if (config.testingType === 'component') {
const { startDevServer } = require('@cypress/webpack-dev-server')
const merge = require('webpack-merge')
const { merge } = require('webpack-merge')
const path = require('path')
const devConfig = require('../../webpack.config.dev')
const webpackConfig = merge(devConfig, {
devServer: {
contentBase: path.join(__dirname, '../../../../public'),
stats: 'none',
static: path.join(__dirname, '../../../../public'),
},
stats: 'none',
})
delete webpackConfig.devServer.client
on('dev-server:start', options => {
return startDevServer({ options, webpackConfig })
})

View file

@ -1,46 +1,47 @@
// NOTE: using "legacy" build as main build requires webpack v5
// import PDFJS from 'pdfjs-dist/webpack'
// To add a new version, copy and adjust one of the `importPDFJS*` functions below,
// add the variant to the "switch" statement, and add to `pdfjsVersions` in webpack.config.js
import 'core-js/features/promise/all-settled' // polyfill for Promise.allSettled (used by pdf.js)
import 'core-js/stable/global-this' // polyfill for globalThis (used by pdf.js)
import 'core-js/stable/promise/all-settled' // polyfill for Promise.allSettled (used by pdf.js)
import getMeta from '../../../utils/meta'
import { createWorker } from '../../../utils/worker'
async function importPDFJS210() {
const cMapUrl = '/js/pdfjs-dist210/cmaps/'
const imageResourcesPath = '/images/pdfjs-dist210'
const [PDFJS, PDFJSViewer, { default: PDFJSWorker }] = await Promise.all([
const [PDFJS, PDFJSViewer] = await Promise.all([
import('pdfjs-dist210/legacy/build/pdf'),
import('pdfjs-dist210/legacy/web/pdf_viewer'),
import('pdfjs-dist210/legacy/build/pdf.worker'),
import('pdfjs-dist210/legacy/web/pdf_viewer.css'),
])
if (typeof window !== 'undefined' && 'Worker' in window) {
PDFJS.GlobalWorkerOptions.workerPort = new PDFJSWorker()
}
createWorker(() => {
PDFJS.GlobalWorkerOptions.workerPort = new Worker(
new URL('pdfjs-dist210/legacy/build/pdf.worker.js', import.meta.url)
)
})
return { PDFJS, PDFJSViewer, PDFJSWorker, cMapUrl, imageResourcesPath }
return { PDFJS, PDFJSViewer, cMapUrl, imageResourcesPath }
}
async function importPDFJS213() {
const cMapUrl = '/js/pdfjs-dist213/cmaps/'
const imageResourcesPath = '/images/pdfjs-dist213'
const [PDFJS, PDFJSViewer, { default: PDFJSWorker }] = await Promise.all([
const [PDFJS, PDFJSViewer] = await Promise.all([
import('pdfjs-dist213/legacy/build/pdf'),
import('pdfjs-dist213/legacy/web/pdf_viewer'),
import('pdfjs-dist213/legacy/build/pdf.worker'),
import('pdfjs-dist213/legacy/web/pdf_viewer.css'),
])
if (typeof window !== 'undefined' && 'Worker' in window) {
PDFJS.GlobalWorkerOptions.workerPort = new PDFJSWorker()
}
createWorker(() => {
PDFJS.GlobalWorkerOptions.workerPort = new Worker(
new URL('pdfjs-dist213/legacy/build/pdf.worker.js', import.meta.url)
)
})
return { PDFJS, PDFJSViewer, PDFJSWorker, cMapUrl, imageResourcesPath }
return { PDFJS, PDFJSViewer, cMapUrl, imageResourcesPath }
}
async function importPDFJS() {
@ -52,7 +53,6 @@ async function importPDFJS() {
case '210':
case 'default':
default:
return importPDFJS210()
}
}

View file

@ -12,12 +12,14 @@ export default class PDFJSWrapper {
}
async init() {
const { PDFJS, PDFJSViewer, PDFJSWorker, cMapUrl, imageResourcesPath } =
await import('./pdf-js-versions').then(m => m.default)
const { PDFJS, PDFJSViewer, cMapUrl, imageResourcesPath } = await import(
'./pdf-js-versions'
).then(m => {
return m.default
})
this.PDFJS = PDFJS
this.PDFJSViewer = PDFJSViewer
this.PDFJSWorker = PDFJSWorker
this.cMapUrl = cMapUrl
this.imageResourcesPath = imageResourcesPath

View file

@ -31,7 +31,8 @@ const SearchBox = ace.require('ace/ext/searchbox')
// Set the base path that ace will fetch modes/snippets/workers from
if (window.aceBasePath !== '') {
syntaxValidationEnabled = true
ace.config.set('basePath', `${window.aceBasePath}`)
ace.config.set('basePath', window.aceBasePath)
ace.config.set('workerPath', window.aceBasePath)
} else {
syntaxValidationEnabled = false
}

View file

@ -0,0 +1,6 @@
export const createWorker = callback => {
const webpackPublicPath = __webpack_public_path__
__webpack_public_path__ = '/'
callback()
__webpack_public_path__ = webpackPublicPath
}

View file

@ -1,16 +1,3 @@
.circle(@size, @background_color) {
display: inline-block;
background-color: @background_color;
border-radius: 50%;
width: @size;
height: @size;
text-align: center;
padding-top: @size / 6.4;
img {
height: @size - @size / 3.2;
}
}
.hub-header {
h2 {
display: inline-block;
@ -39,7 +26,16 @@
display: none;
}
.hub-circle {
.circle(160px, @accent-color-secondary);
display: inline-block;
background-color: @accent-color-secondary;
border-radius: 50%;
width: 160px;
height: 160px;
text-align: center;
//padding-top: 160px / 6.4;
img {
height: 160px - 160px / 3.2;
}
padding-top: 50px;
color: white;
}

View file

@ -101,7 +101,8 @@
.full-size;
left: 20px;
content: '';
background: url(/img/ol-brand/overleaf-o-grey.svg) center / 200px no-repeat;
background: url(../../../public/img/ol-brand/overleaf-o-grey.svg) center /
200px no-repeat;
opacity: 0.2;
pointer-events: none;
}
@ -276,9 +277,9 @@ Ace
.spelling-highlight {
z-index: 3;
position: absolute;
background-image: url(/img/spellcheck-underline.png);
background-image: url(../../../public/img/spellcheck-underline.png);
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
background-image: url(/img/spellcheck-underline@2x.png);
background-image: url(../../../public/img/spellcheck-underline@2x.png);
background-size: 5px 4px;
}
background-repeat: repeat-x;

View file

@ -947,7 +947,8 @@
.review-icon {
display: inline-block;
background: url('/img/ol-icons/review-icon-dark-theme.svg') top/30px no-repeat;
background: url('../../../../public/img/ol-icons/review-icon-dark-theme.svg')
top/30px no-repeat;
width: 30px;
&::before {
@ -957,15 +958,15 @@
button when (@is-overleaf-light = true) {
.review-icon {
background: url('/img/ol-icons/review-icon-light-theme.svg') top/30px
no-repeat;
background: url('../../../../public/img/ol-icons/review-icon-light-theme.svg')
top/30px no-repeat;
}
&.active,
&:active {
.review-icon {
background: url('/img/ol-icons/review-icon-dark-theme.svg') top/30px
no-repeat;
background: url('../../../../public/img/ol-icons/review-icon-dark-theme.svg')
top/30px no-repeat;
}
}
}

View file

@ -247,7 +247,7 @@
}
.spelling-error {
background-image: url(/img/spellcheck-underline.png);
background-image: url(../../../../public/img/spellcheck-underline.png);
background-repeat: repeat-x;
background-position: bottom;
}

View file

@ -13,7 +13,7 @@
}
.img {
max-width: 420px;
background-image: url('/img/ol_plus_sl.png');
background-image: url('../../../public/img/ol_plus_sl.png');
background-size: 100%;
background-repeat: no-repeat;
margin: 20px auto 0;
@ -129,7 +129,7 @@
max-width: 960px;
.img {
max-width: 960px;
background-image: url('/img/homepage.png');
background-image: url('../../../public/img/homepage.png');
background-size: 100%;
background-repeat: no-repeat;
margin: auto;
@ -142,7 +142,7 @@
only screen and (min-resolution: 192dpi),
only screen and (min-resolution: 2dppx) {
.img {
background-image: url('/img/homepage@2x.png');
background-image: url('../../../public/img/homepage@2x.png');
}
}
}
@ -241,13 +241,13 @@
}
.pattern-container {
background: url('/img/pattern-home.png') repeat #f1f1f1;
background: url('../../../public/img/pattern-home.png') repeat #f1f1f1;
border-top: 1px solid @gray-lightest;
border-bottom: 1px solid @gray-lightest;
}
.pattern-grid {
background: url('/img/grid.png') repeat @content-alt-bg-color;
background: url('../../../public/img/grid.png') repeat @content-alt-bg-color;
border-top: 1px solid @gray-lighter;
border-bottom: 1px solid @gray-lighter;
}

View file

@ -117,7 +117,7 @@
position: absolute;
top: 4px;
left: 4px;
background: #fff url(/img/brand/lion.svg) center/20px no-repeat;
background: #fff url(../../../public/img/brand/lion.svg) center/20px no-repeat;
border-radius: 99999px;
width: 26px;
height: 26px;
@ -128,16 +128,16 @@
}
.login-btn-icon-ieee {
background-image: url(/img/other-brands/logo_ieee.svg);
background-image: url(../../../public/img/other-brands/logo_ieee.svg);
}
.login-btn-icon-google {
background-image: url(/img/other-brands/logo_google.svg);
background-image: url(../../../public/img/other-brands/logo_google.svg);
}
.login-btn-icon-twitter {
background-image: url(/img/other-brands/logo_twitter.svg);
background-image: url(../../../public/img/other-brands/logo_twitter.svg);
}
.login-btn-icon-orcid {
background-image: url(/img/other-brands/logo_orcid.svg);
background-image: url(../../../public/img/other-brands/logo_orcid.svg);
}
.login-btn-icon-sharelatex {
background-size: 22px;

View file

@ -1,5 +1,5 @@
.sprite-icon {
background-image: url('/img/sprite.png');
background-image: url('../../../public/img/sprite.png');
}
.sprite-icon-ko {

View file

@ -76,8 +76,8 @@
@toolbar-btn-hover-bg-color: @ol-blue-gray-0;
@toolbar-icon-btn-color: @ol-blue-gray-3;
@toolbar-icon-btn-hover-color: @ol-blue-gray-3;
@editor-header-logo-background: url(/img/ol-brand/overleaf-o.svg) center /
contain no-repeat;
@editor-header-logo-background: url(../../../public/img/ol-brand/overleaf-o.svg)
center / contain no-repeat;
@project-name-color: @ol-blue-gray-3;
@project-rename-link-color: @ol-blue-gray-3;
@project-rename-link-color-hover: @ol-blue-gray-4;
@ -97,7 +97,7 @@
@navbar-title-color: @ol-blue-gray-1;
@navbar-title-color-hover: @ol-blue-gray-2;
@navbar-default-color: @ol-blue-gray-3;
@navbar-brand-image-url: url(/img/ol-brand/overleaf.svg);
@navbar-brand-image-url: url(../../../public/img/ol-brand/overleaf.svg);
@navbar-subdued-color: @ol-blue-gray-3;
@navbar-subdued-hover-bg: @ol-blue-gray-1;

View file

@ -48,11 +48,11 @@
@accent-color-primary: @ol-green;
@accent-color-secondary: @ol-dark-green;
@editor-header-logo-background: url(/img/ol-brand/overleaf-o-white.svg) center /
contain no-repeat;
@editor-header-logo-background: url(../../../public/img/ol-brand/overleaf-o-white.svg)
center / contain no-repeat;
@editor-loading-logo-padding-top: 115.44%;
@editor-loading-logo-background-url: url(/img/ol-brand/overleaf-o-grey.svg);
@editor-loading-logo-foreground-url: url(/img/ol-brand/overleaf-o.svg);
@editor-loading-logo-background-url: url(../../../public/img/ol-brand/overleaf-o-grey.svg);
@editor-loading-logo-foreground-url: url(../../../public/img/ol-brand/overleaf-o.svg);
@editor-search-count-color: @ol-blue-gray-4;
//== Scaffolding
@ -897,7 +897,7 @@
@navbar-subdued-color: #fff;
@navbar-subdued-hover-bg: #fff;
@navbar-subdued-hover-color: @ol-green;
@navbar-brand-image-url: url(/img/ol-brand/overleaf-white.svg);
@navbar-brand-image-url: url(../../../public/img/ol-brand/overleaf-white.svg);
@dropdown-divider-margin: 6px;
@dropdown-item-padding: 4px 20px;

View file

@ -19,7 +19,7 @@
"test:karma:single": "karma start --no-auto-watch --single-run",
"start": "node $NODE_APP_OPTIONS app.js",
"nodemon": "nodemon $NODE_APP_OPTIONS --config nodemon.json",
"webpack": "webpack-dev-server --config webpack.config.dev.js",
"webpack": "webpack serve --config webpack.config.dev.js",
"webpack:production": "webpack --config webpack.config.prod.js",
"webpack:profile": "webpack --config webpack.config.prod.js --profile --json > stats.json",
"format": "prettier --list-different $PWD/'**/*.{js,ts,tsx}'",
@ -210,8 +210,8 @@
"devDependencies": {
"@babel/register": "^7.14.5",
"@cypress/react": "^5.12.1",
"@cypress/webpack-preprocessor": "^5.11.1",
"@cypress/webpack-dev-server": "^1.8.0",
"@cypress/webpack-preprocessor": "^5.11.1",
"@juggle/resize-observer": "^3.3.1",
"@testing-library/cypress": "^8.0.2",
"@testing-library/dom": "^7.31.2",
@ -229,7 +229,7 @@
"acorn-walk": "^7.1.1",
"angular-mocks": "~1.8.0",
"autoprefixer": "^9.7.6",
"babel-loader": "^8.2.2",
"babel-loader": "^8.2.4",
"babel-plugin-angularjs-annotate": "^0.10.0",
"babel-plugin-macros": "^3.1.0",
"c8": "^7.2.0",
@ -239,8 +239,9 @@
"chaid": "^1.0.2",
"cheerio": "^1.0.0-rc.3",
"content-disposition": "^0.5.0",
"copy-webpack-plugin": "^5.1.1",
"css-loader": "^3.5.2",
"copy-webpack-plugin": "^10.2.4",
"css-loader": "^6.7.1",
"css-minimizer-webpack-plugin": "^3.4.1",
"cypress": "^9.5.1",
"es6-promise": "^4.2.8",
"escodegen": "^2.0.0",
@ -259,35 +260,33 @@
"eslint-plugin-react": "^7.27.0",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-standard": "^5.0.0",
"expose-loader": "^0.7.5",
"expose-loader": "^3.1.0",
"fetch-mock": "^9.10.2",
"file-loader": "^5.0.2",
"glob": "^7.1.6",
"handlebars-loader": "^1.7.1",
"i18next-scanner": "^3.0.0",
"jsdom": "^16.7.0",
"jsdom": "^19.0.0",
"jsdom-global": "^3.0.2",
"karma": "^5.0.2",
"karma": "^6.3.17",
"karma-chai-sinon": "^0.1.5",
"karma-chrome-launcher": "^3.1.0",
"karma-mocha": "^2.0.0",
"karma-mocha-reporter": "^2.2.5",
"karma-requirejs": "^1.1.0",
"karma-webpack": "^4.0.2",
"karma-webpack": "^5.0.0",
"less": "^3.11.1",
"less-loader": "^6.0.0",
"less-loader": "^10.2.0",
"less-plugin-autoprefix": "^2.0.0",
"mensch": "^0.3.4",
"mini-css-extract-plugin": "^0.8.0",
"mini-css-extract-plugin": "^2.6.0",
"mkdirp": "0.5.1",
"mocha": "^8.4.0",
"mock-fs": "^5.1.2",
"nock": "^13.1.1",
"node-fetch": "^2.6.7",
"nodemon": "^2.0.6",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"pirates": "^4.0.1",
"postcss-loader": "^3.0.0",
"postcss-loader": "^6.2.1",
"prettier": "2.5.1",
"requirejs": "^2.3.6",
"samlp": "^3.4.1",
@ -296,16 +295,16 @@
"sinon-chai": "^3.7.0",
"sinon-mongoose": "^2.3.0",
"socket.io-mock": "^1.3.1",
"terser-webpack-plugin": "^2.3.6",
"terser-webpack-plugin": "^5.3.1",
"timekeeper": "^2.2.0",
"to-string-loader": "^1.1.6",
"to-string-loader": "^1.2.0",
"typescript": "^4.5.5",
"val-loader": "^1.1.1",
"webpack": "^4.44.2",
"webpack-assets-manifest": "^4.0.6",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^4.2.2",
"worker-loader": "^2.0.0"
"val-loader": "^4.0.0",
"webpack": "^5.71.0",
"webpack-assets-manifest": "^5.1.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4",
"webpack-merge": "^5.8.0",
"worker-loader": "^3.0.8"
}
}

View file

@ -1,7 +1,7 @@
{
"compilerOptions": {
"target": "esnext" /* Specify ECMAScript target version */,
"module": "commonjs" /* Specify module code generation */,
"module": "es2020" /* Specify module code generation */,
"allowJs": true /* Allow JavaScript files to be compiled. */,
// "checkJs": true /* Report errors in .js files. */,
"jsx": "preserve" /* Specify JSX code generation */,

2
services/web/types/globals.d.ts vendored Normal file
View file

@ -0,0 +1,2 @@
// eslint-disable-next-line camelcase,no-unused-vars
declare let __webpack_public_path__: string

View file

@ -1,5 +1,5 @@
const webpack = require('webpack')
const merge = require('webpack-merge')
const { merge } = require('webpack-merge')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const base = require('./webpack.config')
@ -28,19 +28,26 @@ module.exports = merge(base, {
// Expose dev server at www.dev-overleaf.com
host: '0.0.0.0',
port: 3808,
public: 'www.dev-overleaf.com:443',
// Customise output to the (node) console
stats: {
colors: true, // Enable some coloured highlighting
// Hide some overly verbose output
performance: false, // Disable as code is uncompressed in dev mode
hash: false,
version: false,
chunks: false,
modules: false,
// Hide copied assets from output
excludeAssets: [/^js\/ace/, /^js\/libs/, /^js\/cmaps/],
client: {
webSocketURL: 'auto://0.0.0.0:0/ws',
},
allowedHosts: '.dev-overleaf.com',
setupMiddlewares(middlewares, devServer) {
devServer.app.get('/status', (req, res) => res.send('webpack is up'))
return middlewares
},
},
// Customise output to the (node) console
stats: {
colors: true, // Enable some coloured highlighting
// Hide some overly verbose output
performance: false, // Disable as code is uncompressed in dev mode
hash: false,
version: false,
chunks: false,
modules: false,
// Hide copied assets from output
excludeAssets: [/^js\/ace/, /^js\/libs/, /^js\/cmaps/],
},
})

View file

@ -9,7 +9,6 @@ const PackageVersions = require('./app/src/infrastructure/PackageVersions')
// Generate a hash of entry points, including modules
const entryPoints = {
serviceWorker: './frontend/js/serviceWorker.js',
main: './frontend/js/main.js',
ide: './frontend/js/ide.js',
'ide-detached': './frontend/js/ide-detached.js',
@ -19,6 +18,13 @@ const entryPoints = {
'light-style': './frontend/stylesheets/light-style.less',
}
// ServiceWorker at /serviceWorker.js
entryPoints.serviceWorker = {
import: './frontend/js/serviceWorker.js',
publicPath: '/',
filename: 'serviceWorker.js',
}
// Add entrypoints for each "page"
glob
.sync(path.join(__dirname, 'modules/*/frontend/js/pages/**/*.js'))
@ -72,7 +78,7 @@ module.exports = {
publicPath: '/',
// By default write into js directory
filename: 'js/[name].js',
filename: 'js/[name]-[contenthash].js',
// Output as UMD bundle (allows main JS to import with CJS, AMD or global
// style code bundles
@ -101,36 +107,7 @@ module.exports = {
},
},
],
},
{
// Wrap worker scripts in a Web Worker
test: /\.worker\.js$/,
use: [
{
loader: 'worker-loader',
options: {
// Write into js directory (note: customising this is not possible
// with pdfjs-dist/webpack auto loader)
name: 'js/[name].[contenthash].js',
// Override dynamically-set publicPath to explicitly use root.
// This prevents a security problem where the Worker - normally
// loaded from a CDN - has cross-origin issues, by forcing it to not
// be loaded from the CDN
publicPath: '/',
},
},
],
},
{
test: /serviceWorker.js$/,
use: [
{
loader: 'worker-loader',
options: {
name: 'serviceWorker.js',
},
},
],
type: 'javascript/auto',
},
{
// Pass Less files through less-loader/css-loader/mini-css-extract-
@ -145,9 +122,9 @@ module.exports = {
// Runs autoprefixer on CSS via postcss
loader: 'postcss-loader',
options: {
// Uniquely identifies the postcss plugin (required by webpack)
ident: 'postcss',
plugins: [require('autoprefixer')],
postcssOptions: {
plugins: ['autoprefixer'],
},
},
},
// Compiles the Less syntax to CSS
@ -162,32 +139,18 @@ module.exports = {
{
// Load fonts
test: /\.(woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {
// Output to public/font
outputPath: 'fonts',
publicPath: '/fonts/',
name: '[name].[ext]',
},
},
],
type: 'asset/resource',
generator: {
filename: 'fonts/[name]-[contenthash][ext]',
},
},
{
// Load images (static files)
test: /\.(svg|gif|png|jpg|pdf)$/,
use: [
{
loader: 'file-loader',
options: {
// Output to public/images
outputPath: 'images',
publicPath: '/images/',
name: '[name].[ext]',
},
},
],
type: 'asset/resource',
generator: {
filename: 'images/[name]-[contenthash][ext]',
},
},
{
// These options are necessary for handlebars to have access to helper
@ -234,21 +197,9 @@ module.exports = {
use: [
{
loader: 'expose-loader',
options: 'jQuery',
},
{
loader: 'expose-loader',
options: '$',
},
],
},
{
// Expose angular global variable
test: require.resolve('angular'),
use: [
{
loader: 'expose-loader',
options: 'angular',
options: {
exposes: ['$', 'jQuery'],
},
},
],
},
@ -269,13 +220,8 @@ module.exports = {
},
symlinks: false,
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
},
// Split out files into separate (derived) bundles if they are shared between
// multiple (explicit) bundles, according to some webpack heuristics
optimization: {
splitChunks: {
chunks: 'all',
fallback: {
events: require.resolve('events'),
},
},
@ -285,6 +231,13 @@ module.exports = {
new WebpackAssetsManifest({
entrypoints: true,
publicPath: true,
output: 'manifest.json',
}),
// Ensure that process.env.RESET_APP_DATA_TIMER is defined, to avoid an error.
// https://github.com/algolia/algoliasearch-client-javascript/issues/756
new webpack.EnvironmentPlugin({
RESET_APP_DATA_TIMER: '120000',
}),
// Prevent moment from loading (very large) locale files that aren't used
@ -294,62 +247,71 @@ module.exports = {
}),
// Copy the required files for loading MathJax from MathJax NPM package
new CopyPlugin(
[
{ from: 'MathJax.js', to: 'js/libs/mathjax' },
{ from: 'config/**/*', to: 'js/libs/mathjax' },
{ from: 'extensions/**/*', to: 'js/libs/mathjax' },
{ from: 'localization/en/**/*', to: 'js/libs/mathjax' },
{ from: 'jax/output/HTML-CSS/fonts/TeX/**/*', to: 'js/libs/mathjax' },
{ from: 'jax/output/HTML-CSS/**/*.js', to: 'js/libs/mathjax' },
{ from: 'jax/element/**/*', to: 'js/libs/mathjax' },
{ from: 'jax/input/**/*', to: 'js/libs/mathjax' },
{ from: 'fonts/HTML-CSS/TeX/woff/*', to: 'js/libs/mathjax' },
],
{
context: mathjaxDir,
}
),
new CopyPlugin(
[
new CopyPlugin({
patterns: [
{ from: 'MathJax.js', to: 'js/libs/mathjax', context: mathjaxDir },
{ from: 'config/**/*', to: 'js/libs/mathjax', context: mathjaxDir },
{
from: 'extensions/**/*',
globOptions: {
// https://github.com/mathjax/MathJax/issues/2403
ignore: ['**/mathmaps/*.js'],
},
to: 'js/libs/mathjax',
context: mathjaxDir,
},
{
from: 'localization/en/**/*',
to: 'js/libs/mathjax',
context: mathjaxDir,
},
{
from: 'jax/output/HTML-CSS/fonts/TeX/**/*',
to: 'js/libs/mathjax',
context: mathjaxDir,
},
{
from: 'jax/output/HTML-CSS/**/*.js',
to: 'js/libs/mathjax',
context: mathjaxDir,
},
{
from: 'jax/element/**/*',
to: 'js/libs/mathjax',
context: mathjaxDir,
},
{ from: 'jax/input/**/*', to: 'js/libs/mathjax', context: mathjaxDir },
{
from: 'fonts/HTML-CSS/TeX/woff/*',
to: 'js/libs/mathjax',
context: mathjaxDir,
},
{
from: 'libs/sigma-master',
to: 'js/libs/sigma-master',
context: vendorDir,
},
],
{
context: vendorDir,
}
),
new CopyPlugin(
[
{
from: 'src-min-noconflict',
to: `js/ace-${PackageVersions.version.ace}/`,
context: aceDir,
},
...pdfjsVersions.flatMap(version => {
const dir = getModuleDirectory(version)
// Copy CMap files (used to provide support for non-Latin characters)
// and static images from pdfjs-dist package to build output.
return [
{ from: `cmaps`, to: `js/${version}/cmaps`, context: dir },
{
from: `legacy/web/images`,
to: `images/${version}`,
context: dir,
},
]
}),
],
{
context: aceDir,
}
),
new CopyPlugin([
...pdfjsVersions.flatMap(version => {
const dir = getModuleDirectory(version)
// Copy CMap files (used to provide support for non-Latin characters)
// and static images from pdfjs-dist package to build output.
return [
{ from: `${dir}/cmaps`, to: `js/${version}/cmaps` },
{
from: `${dir}/legacy/web/images`,
to: `images/${version}`,
},
]
}),
]),
}),
],
}

View file

@ -1,13 +1,11 @@
const merge = require('webpack-merge')
const { merge } = require('webpack-merge')
const TerserPlugin = require('terser-webpack-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const base = require('./webpack.config')
// Use "smart" merge: attempts to combine loaders targeting the same file type,
// overriding the base config
module.exports = merge.smart(
module.exports = merge(
base,
{
mode: 'production',
@ -15,31 +13,6 @@ module.exports = merge.smart(
// Enable a full source map. Generates a comment linking to the source map
devtool: 'hidden-source-map',
output: {
// Override filename to include hash for immutable caching
filename: 'js/[name]-[chunkhash].js',
},
module: {
rules: [
{
// Override base font loading to add hash to filename so that we can
// use "immutable" caching
test: /\.(woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'fonts',
publicPath: '/fonts/',
name: '[name]-[hash]-1.[ext]',
},
},
],
},
],
},
optimization: {
// Minify JS (with Terser) and CSS (with cssnano)
minimizer: [
@ -49,7 +22,7 @@ module.exports = merge.smart(
keep_fnames: /(Error|Exception)$/,
},
}),
new OptimizeCssAssetsPlugin(),
new CssMinimizerPlugin(),
],
},
@ -58,7 +31,7 @@ module.exports = merge.smart(
new MiniCssExtractPlugin({
// Output to public/stylesheets directory and append hash for immutable
// caching
filename: 'stylesheets/[name]-[chunkhash].css',
filename: 'stylesheets/[name]-[contenthash].css',
}),
],
},

View file

@ -1,14 +1,16 @@
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const merge = require('webpack-merge')
const { merge } = require('webpack-merge')
const base = require('./webpack.config')
module.exports = merge(base, {
const config = merge(base, {
mode: 'development',
plugins: [new MiniCssExtractPlugin()],
// Karma configures entry & output for us, so disable these
entry: null,
output: null,
})
// Karma configures entry & output for us, so disable these
delete config.entry
delete config.output
module.exports = config