@@ -3,6 +3,7 @@ const path = require('path');
3
3
const merge = require ( 'lodash.merge' ) ;
4
4
const nodeExternals = require ( 'webpack-node-externals' ) ;
5
5
const webpack = require ( 'webpack' ) ;
6
+ const TerserPlugin = require ( "terser-webpack-plugin" )
6
7
7
8
const DEFAULT_CHUNK_FILENAME = 'chunks/[name].[chunkhash].js' ;
8
9
const DEFAULT_ASSET_FILENAME = 'assets/[name].[hash][ext][query]' ;
@@ -30,14 +31,15 @@ const toPath = path => {
30
31
class ScratchWebpackConfigBuilder {
31
32
/**
32
33
* @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.
34
35
* @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 `/`.
35
37
* @param {boolean } [options.enableReact] Whether to enable React and JSX support.
36
38
* @param {string } [options.libraryName] The name of the library to build. Shorthand for `output.library.name`.
37
39
* @param {string|URL } [options.srcPath] The absolute path to the source files. Defaults to `src` under `rootPath`.
38
40
* @param {boolean } [options.shouldSplitChunks] Whether to enable spliting code to chunks.
39
41
*/
40
- constructor ( { distPath, enableReact, libraryName, rootPath, srcPath, shouldSplitChunks } ) {
42
+ constructor ( { distPath, enableReact, enableTs , libraryName, rootPath, srcPath, publicPath = '/' , shouldSplitChunks } ) {
41
43
const isProduction = process . env . NODE_ENV === 'production' ;
42
44
const mode = isProduction ? 'production' : 'development' ;
43
45
@@ -58,6 +60,14 @@ class ScratchWebpackConfigBuilder {
58
60
} : path . resolve ( this . _srcPath , 'index' ) ,
59
61
optimization : {
60
62
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
+ ] ,
61
71
...(
62
72
shouldSplitChunks ? {
63
73
splitChunks : {
@@ -74,6 +84,8 @@ class ScratchWebpackConfigBuilder {
74
84
assetModuleFilename : DEFAULT_ASSET_FILENAME ,
75
85
chunkFilename : DEFAULT_CHUNK_FILENAME ,
76
86
path : this . _distPath ,
87
+ // See https://github.com/scratchfoundation/scratch-editor/pull/25/files/9bc537f9bce35ee327b74bd6715d6c5140f73937#r1763073684
88
+ publicPath,
77
89
library : {
78
90
name : libraryName ,
79
91
type : 'umd2'
@@ -90,6 +102,7 @@ class ScratchWebpackConfigBuilder {
90
102
'.jsx'
91
103
] : [ ]
92
104
) ,
105
+ ...( enableTs ? [ '.ts' , '.tsx' ] : [ ] ) ,
93
106
// webpack supports '...' to include defaults, but eslint does not
94
107
'.js' ,
95
108
'.json'
@@ -98,12 +111,18 @@ class ScratchWebpackConfigBuilder {
98
111
module : {
99
112
rules : [
100
113
{
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 $ / ) ,
102
117
loader : 'babel-loader' ,
103
118
exclude : [
104
119
{
105
120
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 [ \\ / ] / ]
107
126
}
108
127
] ,
109
128
options : {
@@ -196,9 +215,13 @@ class ScratchWebpackConfigBuilder {
196
215
]
197
216
}
198
217
] : [ ]
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
+ } ] : [ ] ) ,
200
224
] ,
201
-
202
225
} ,
203
226
plugins : [
204
227
new webpack . ProvidePlugin ( {
@@ -238,6 +261,16 @@ class ScratchWebpackConfigBuilder {
238
261
return this ;
239
262
}
240
263
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
+
241
274
/**
242
275
* Set the target environment for this configuration.
243
276
* @param {string } target The target environment, like `node`, `browserslist`, etc.
0 commit comments