@@ -3,6 +3,7 @@ const path = require('path');
33const merge = require ( 'lodash.merge' ) ;
44const nodeExternals = require ( 'webpack-node-externals' ) ;
55const webpack = require ( 'webpack' ) ;
6+ const TerserPlugin = require ( "terser-webpack-plugin" )
67
78const DEFAULT_CHUNK_FILENAME = 'chunks/[name].[chunkhash].js' ;
89const DEFAULT_ASSET_FILENAME = 'assets/[name].[hash][ext][query]' ;
@@ -30,14 +31,15 @@ const toPath = path => {
3031class ScratchWebpackConfigBuilder {
3132 /**
3233 * @param {object } options Options for the webpack configuration.
33- * @param {string|URL } options.rootPath The absolute path to the project root.
34+ * @param {string|URL } [ options.rootPath] The absolute path to the project root.
3435 * @param {string|URL } [options.distPath] The absolute path to build output. Defaults to `dist` under `rootPath`.
36+ * @param {string|URL } [options.publicPath] The public location where the output assets will be located. Defaults to `/`.
3537 * @param {boolean } [options.enableReact] Whether to enable React and JSX support.
3638 * @param {string } [options.libraryName] The name of the library to build. Shorthand for `output.library.name`.
3739 * @param {string|URL } [options.srcPath] The absolute path to the source files. Defaults to `src` under `rootPath`.
3840 * @param {boolean } [options.shouldSplitChunks] Whether to enable spliting code to chunks.
3941 */
40- constructor ( { distPath, enableReact, libraryName, rootPath, srcPath, shouldSplitChunks } ) {
42+ constructor ( { distPath, enableReact, enableTs , libraryName, rootPath, srcPath, publicPath = '/' , shouldSplitChunks } ) {
4143 const isProduction = process . env . NODE_ENV === 'production' ;
4244 const mode = isProduction ? 'production' : 'development' ;
4345
@@ -58,6 +60,14 @@ class ScratchWebpackConfigBuilder {
5860 } : path . resolve ( this . _srcPath , 'index' ) ,
5961 optimization : {
6062 minimize : isProduction ,
63+ minimizer : [
64+ new TerserPlugin ( {
65+ // Limiting Terser to use only 2 threads. At least for building scratch-gui
66+ // this results in a performance gain (from ~60s to ~36s) on a MacBook with
67+ // M1 Pro and 32GB of RAM and halving the memory usage (from ~11GB at peaks to ~6GB)
68+ parallel : 2
69+ } )
70+ ] ,
6171 ...(
6272 shouldSplitChunks ? {
6373 splitChunks : {
@@ -74,6 +84,8 @@ class ScratchWebpackConfigBuilder {
7484 assetModuleFilename : DEFAULT_ASSET_FILENAME ,
7585 chunkFilename : DEFAULT_CHUNK_FILENAME ,
7686 path : this . _distPath ,
87+ // See https://github.com/scratchfoundation/scratch-editor/pull/25/files/9bc537f9bce35ee327b74bd6715d6c5140f73937#r1763073684
88+ publicPath,
7789 library : {
7890 name : libraryName ,
7991 type : 'umd2'
@@ -90,6 +102,7 @@ class ScratchWebpackConfigBuilder {
90102 '.jsx'
91103 ] : [ ]
92104 ) ,
105+ ...( enableTs ? [ '.ts' , '.tsx' ] : [ ] ) ,
93106 // webpack supports '...' to include defaults, but eslint does not
94107 '.js' ,
95108 '.json'
@@ -98,12 +111,18 @@ class ScratchWebpackConfigBuilder {
98111 module : {
99112 rules : [
100113 {
101- test : enableReact ? / \. [ c m ] ? j s x ? $ / : / \. [ c m ] ? j s $ / ,
114+ test : enableReact ?
115+ ( enableTs ? / \. [ c m ] ? [ j t ] s x ? $ / : / \. [ c m ] ? j s x ? $ / ) :
116+ ( enableTs ? / \. [ c m ] ? [ j t ] s $ / : / \. [ c m ] ? j s $ / ) ,
102117 loader : 'babel-loader' ,
103118 exclude : [
104119 {
105120 and : [ / n o d e _ m o d u l e s / ] ,
106- not : [ / n o d e _ m o d u l e s [ \\ / ] .* s c r a t c h / ]
121+
122+ // Some scratch pakcages point to their source (as opposed to a pre-built version)
123+ // for their browser or webpack target. So we need to process them (at the minimum
124+ // to resolve the JSX syntax).
125+ not : [ / n o d e _ m o d u l e s [ \\ / ] s c r a t c h - ( p a i n t | r e n d e r | s v g - r e n d e r e r | v m ) [ \\ / ] s r c [ \\ / ] / ]
107126 }
108127 ] ,
109128 options : {
@@ -196,9 +215,13 @@ class ScratchWebpackConfigBuilder {
196215 ]
197216 }
198217 ] : [ ]
199- )
218+ ) ,
219+ ...( enableTs ? [ {
220+ test : enableReact ? / \. [ c m ] ? t s x ? $ / : / \. [ c m ] ? t s $ / ,
221+ loader : 'ts-loader' ,
222+ exclude : [ / n o d e _ m o d u l e s / ]
223+ } ] : [ ] ) ,
200224 ] ,
201-
202225 } ,
203226 plugins : [
204227 new webpack . ProvidePlugin ( {
@@ -238,6 +261,16 @@ class ScratchWebpackConfigBuilder {
238261 return this ;
239262 }
240263
264+ /**
265+ * Append new externals to the current configuration object.
266+ * @param {string[] } externals Externals to add.
267+ * @returns {this }
268+ */
269+ addExternals ( externals ) {
270+ this . _config . externals = ( this . _config . externals ?? [ ] ) . concat ( externals ) ;
271+ return this ;
272+ }
273+
241274 /**
242275 * Set the target environment for this configuration.
243276 * @param {string } target The target environment, like `node`, `browserslist`, etc.
0 commit comments