Skip to content

Commit 7e0ca07

Browse files
Merge pull request #54 from scratchfoundation/nextgen
Add TypeScript support & make externals configurable
2 parents 03f9872 + ec47b45 commit 7e0ca07

File tree

3 files changed

+161
-13
lines changed

3 files changed

+161
-13
lines changed

package-lock.json

+121-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"postcss-loader": "4.3.0",
5353
"postcss-simple-vars": "^5.0.1",
5454
"style-loader": "4.0.0",
55+
"ts-loader": "^9.5.1",
5556
"url-loader": "4.1.1",
5657
"webpack": "^5.90.3"
5758
}

src/index.cjs

+39-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const path = require('path');
33
const merge = require('lodash.merge');
44
const nodeExternals = require('webpack-node-externals');
55
const webpack = require('webpack');
6+
const TerserPlugin = require("terser-webpack-plugin")
67

78
const DEFAULT_CHUNK_FILENAME = 'chunks/[name].[chunkhash].js';
89
const DEFAULT_ASSET_FILENAME = 'assets/[name].[hash][ext][query]';
@@ -30,14 +31,15 @@ const toPath = path => {
3031
class 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 ? /\.[cm]?jsx?$/ : /\.[cm]?js$/,
114+
test: enableReact ?
115+
(enableTs ? /\.[cm]?[jt]sx?$/ : /\.[cm]?jsx?$/) :
116+
(enableTs ? /\.[cm]?[jt]s$/ : /\.[cm]?js$/),
102117
loader: 'babel-loader',
103118
exclude: [
104119
{
105120
and: [/node_modules/],
106-
not: [/node_modules[\\/].*scratch/]
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: [/node_modules[\\/]scratch-(paint|render|svg-renderer|vm)[\\/]src[\\/]/]
107126
}
108127
],
109128
options: {
@@ -196,9 +215,13 @@ class ScratchWebpackConfigBuilder {
196215
]
197216
}
198217
] : []
199-
)
218+
),
219+
...(enableTs ? [{
220+
test: enableReact ? /\.[cm]?tsx?$/ : /\.[cm]?ts$/,
221+
loader: 'ts-loader',
222+
exclude: [/node_modules/]
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

Comments
 (0)