Skip to content

Commit 8073945

Browse files
committed
fix(build): Add externals for libraries
1 parent 67574b6 commit 8073945

7 files changed

Lines changed: 72 additions & 57 deletions

File tree

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"@typescript-eslint/eslint-plugin": "^2.27.0",
3939
"@typescript-eslint/parser": "^2.27.0",
4040
"copy-webpack-plugin": "^5.1.1",
41-
"cross-spawn": "^7.0.2",
41+
"cross-spawn": "7.0.3",
4242
"css-loader": "^3.4.2",
4343
"enzyme": "^3.11.0",
4444
"enzyme-adapter-react-16": "^1.15.2",
@@ -67,7 +67,7 @@
6767
},
6868
"devDependencies": {
6969
"@types/copy-webpack-plugin": "^5.0.0",
70-
"@types/cross-spawn": "^6.0.1",
70+
"@types/cross-spawn": "^6.0.2",
7171
"@types/eslint": "^7.2.0",
7272
"@types/jest": "^25.2.1",
7373
"@types/mini-css-extract-plugin": "^0.9.1",

src/common/paths.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import path from "path";
22

33
const ROOT_PATH = path.resolve(process.cwd());
4+
const NODE_MODULES_PATH = path.resolve(ROOT_PATH, "node_modules");
45
const CONFIG_PATH = path.resolve(ROOT_PATH, "config");
56
const SOURCE_PATH = path.resolve(ROOT_PATH, "src");
67
const ASSETS_PATH = path.resolve(ROOT_PATH, "public");
78
const OUTPUT_PATH = path.resolve(ROOT_PATH, "dist");
89
const OUTPUT_PUBLIC_PATH = "/";
910

10-
export { ROOT_PATH, CONFIG_PATH, SOURCE_PATH, ASSETS_PATH, OUTPUT_PATH, OUTPUT_PUBLIC_PATH };
11+
export { ROOT_PATH, NODE_MODULES_PATH, CONFIG_PATH, SOURCE_PATH, ASSETS_PATH, OUTPUT_PATH, OUTPUT_PUBLIC_PATH };

src/webpack/resolveExternals.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
import type webpack from "webpack";
22

3-
export default (isDevelopment: boolean, isLibrary?: true): webpack.ExternalsElement => {
4-
if (isDevelopment || isLibrary) {
5-
return {};
3+
export default (isLibrary: boolean): webpack.ExternalsElement => {
4+
if (isLibrary) {
5+
// UMD only supports an object
6+
return {
7+
react: {
8+
amd: "react",
9+
commonjs: "react",
10+
commonjs2: "react",
11+
root: "React",
12+
},
13+
"react-dom": {
14+
amd: "react-dom",
15+
commonjs: "react-dom",
16+
commonjs2: "react-dom",
17+
root: "ReactDOM",
18+
},
19+
};
620
}
721

822
return {

src/webpack/resolveModuleRules.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import MiniCssExtractPlugin from "mini-css-extract-plugin";
22
import { SOURCE_PATH } from "../common/paths";
33
import type webpack from "webpack";
44

5-
const getCssLoaders = (isDevelopment: boolean): (string | webpack.RuleSetLoader)[] => {
5+
const getCssLoaders = (isDevelopment: boolean, isLibrary: boolean): (string | webpack.RuleSetLoader)[] => {
66
const styleLoader = "style-loader";
77
const miniCssExtractPluginLoader = MiniCssExtractPlugin.loader;
88
const typingsCssModulesLoader = {
@@ -27,18 +27,22 @@ const getCssLoaders = (isDevelopment: boolean): (string | webpack.RuleSetLoader)
2727
},
2828
};
2929

30+
if (isLibrary) {
31+
return isDevelopment ? [styleLoader, typingsCssModulesLoader, cssLoader] : [styleLoader, cssLoader];
32+
}
33+
3034
return isDevelopment ? [styleLoader, typingsCssModulesLoader, cssLoader] : [miniCssExtractPluginLoader, cssLoader];
3135
};
3236

33-
export default (isDevelopment: boolean): webpack.RuleSetRule[] => [
37+
export default (isDevelopment: boolean, isLibrary: boolean): webpack.RuleSetRule[] => [
3438
// All .ts and .tsx files will be loaded with ts-loader
3539
{ test: /\.ts(x?)$/, include: SOURCE_PATH, use: [{ loader: "ts-loader" }] },
3640
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
3741
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" },
3842
{
3943
test: /\.scss$/,
4044
use: [
41-
...getCssLoaders(isDevelopment),
45+
...getCssLoaders(isDevelopment, isLibrary),
4246
{
4347
loader: "sass-loader",
4448
options: {
@@ -49,7 +53,7 @@ export default (isDevelopment: boolean): webpack.RuleSetRule[] => [
4953
},
5054
{
5155
test: /\.css$/,
52-
use: [...getCssLoaders(isDevelopment)],
56+
use: [...getCssLoaders(isDevelopment, isLibrary)],
5357
},
5458
{ test: /\.svg$/, use: ["@svgr/webpack", "url-loader"] },
5559
];

src/webpack/resolvePlugins.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@ import HtmlWebpackPlugin from "html-webpack-plugin";
55
import CopyWebpackPlugin from "copy-webpack-plugin";
66
import { ASSETS_PATH, OUTPUT_PATH, OUTPUT_PUBLIC_PATH } from "../common/paths";
77

8-
// TODO: move this to the main file and convert the webpack to a function
9-
import getArgumentValue from "../common/getArgumentValue";
10-
const isLibrary = getArgumentValue(process.argv, "type").toLowerCase() === "library";
11-
12-
export default (isDevelopment: boolean, version: string): webpack.Plugin[] => {
8+
export default (isDevelopment: boolean, isLibrary: boolean, version: string): webpack.Plugin[] => {
139
const noOpFunction = (): undefined => undefined;
1410
const miniCssExtractPlugin = new MiniCssExtractPlugin({
1511
filename: isDevelopment ? "styles.css" : "styles.[hash:5].css",
@@ -29,11 +25,11 @@ export default (isDevelopment: boolean, version: string): webpack.Plugin[] => {
2925
const watchIgnorePlugin = new webpack.WatchIgnorePlugin([/scss\.d\.ts$/]);
3026
const hotModuleReplacementPlugin = new webpack.HotModuleReplacementPlugin();
3127

32-
return [
33-
miniCssExtractPlugin,
34-
!isLibrary ? copyWebpackPlugin : noOpFunction,
35-
!isLibrary ? htmlWebpackPlugin : noOpFunction,
36-
watchIgnorePlugin,
37-
isDevelopment ? hotModuleReplacementPlugin : noOpFunction,
38-
];
28+
if (isLibrary) {
29+
return isDevelopment ? [watchIgnorePlugin, hotModuleReplacementPlugin] : [watchIgnorePlugin];
30+
}
31+
32+
return isDevelopment
33+
? [miniCssExtractPlugin, copyWebpackPlugin, htmlWebpackPlugin, watchIgnorePlugin, hotModuleReplacementPlugin]
34+
: [miniCssExtractPlugin, copyWebpackPlugin, htmlWebpackPlugin, watchIgnorePlugin];
3935
};

src/webpack/webpack.config.app.ts

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,53 @@
11
import path from "path";
2+
import { ROOT_PATH, OUTPUT_PATH, OUTPUT_PUBLIC_PATH } from "../common/paths";
3+
import resolveAliases from "./resolveAliases";
24
import resolveExternals from "./resolveExternals";
35
import resolveModuleRules from "./resolveModuleRules";
46
import resolvePlugins from "./resolvePlugins";
57
import resolveVersion from "./resolveVersion";
6-
import { ROOT_PATH, OUTPUT_PATH, OUTPUT_PUBLIC_PATH } from "../common/paths";
8+
79
import type webpack from "webpack";
810

911
const isDevelopment = process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev";
1012
const version = resolveVersion(isDevelopment);
1113

1214
const webpackConfig: webpack.Configuration = {
15+
devServer: isDevelopment
16+
? {
17+
https: true,
18+
inline: true,
19+
hot: true,
20+
contentBase: [OUTPUT_PATH, ROOT_PATH],
21+
publicPath: OUTPUT_PUBLIC_PATH,
22+
historyApiFallback: true,
23+
}
24+
: undefined,
25+
26+
// See https://webpack.js.org/configuration/devtool/
27+
devtool: isDevelopment ? "cheap-module-eval-source-map" : "source-map",
28+
29+
externals: resolveExternals(false),
30+
1331
mode: isDevelopment ? "development" : "production",
1432

1533
entry: path.resolve(ROOT_PATH, "./src/index.tsx"),
34+
1635
output: {
1736
filename: "bundle.[hash:5].min.js",
1837
path: OUTPUT_PATH,
1938
publicPath: OUTPUT_PUBLIC_PATH,
2039
},
2140

22-
devServer: {
23-
https: true,
24-
inline: true,
25-
hot: true,
26-
contentBase: [OUTPUT_PATH, ROOT_PATH],
27-
publicPath: OUTPUT_PUBLIC_PATH,
28-
historyApiFallback: true,
29-
},
30-
31-
// See https://webpack.js.org/configuration/devtool/
32-
devtool: isDevelopment ? "cheap-module-eval-source-map" : "source-map",
33-
3441
resolve: {
35-
// Add resolvable extensions.
42+
alias: resolveAliases(),
3643
extensions: [".ts", ".tsx", ".scss", ".js", ".jsx", ".json"],
3744
},
3845

39-
// When importing a module whose path matches one of the following, just
40-
// assume a corresponding global variable exists and use that instead.
41-
// This is important because it allows us to avoid bundling all of our
42-
// dependencies, which allows browsers to cache those libraries between builds.
43-
externals: resolveExternals(isDevelopment),
44-
4546
module: {
46-
rules: resolveModuleRules(isDevelopment),
47+
rules: resolveModuleRules(isDevelopment, false),
4748
},
4849

49-
plugins: resolvePlugins(isDevelopment, version),
50+
plugins: resolvePlugins(isDevelopment, false, version),
5051
};
5152

5253
export default webpackConfig;
Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,41 @@
11
import path from "path";
2+
import { ROOT_PATH, OUTPUT_PATH } from "../common/paths";
3+
import resolveAliases from "./resolveAliases";
24
import resolveExternals from "./resolveExternals";
35
import resolveModuleRules from "./resolveModuleRules";
46
import resolvePlugins from "./resolvePlugins";
57
import resolveVersion from "./resolveVersion";
6-
import { ROOT_PATH, OUTPUT_PATH } from "../common/paths";
78
import type webpack from "webpack";
89

910
const isDevelopment = process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev";
1011
const version = resolveVersion(isDevelopment);
1112

1213
const webpackConfig: webpack.Configuration = {
14+
// See https://webpack.js.org/configuration/devtool/
15+
devtool: isDevelopment ? "cheap-module-eval-source-map" : "source-map",
16+
17+
externals: resolveExternals(true),
18+
1319
mode: isDevelopment ? "development" : "production",
1420

1521
entry: path.resolve(ROOT_PATH, "./src/index.tsx"),
22+
1623
output: {
1724
filename: "index.min.js",
1825
path: OUTPUT_PATH,
26+
libraryTarget: "commonjs2",
1927
},
2028

21-
// See https://webpack.js.org/configuration/devtool/
22-
devtool: isDevelopment ? "cheap-module-eval-source-map" : "source-map",
23-
2429
resolve: {
25-
// Add resolvable extensions.
30+
alias: resolveAliases(),
2631
extensions: [".ts", ".tsx", ".scss", ".js", ".jsx", ".json"],
2732
},
2833

29-
// When importing a module whose path matches one of the following, just
30-
// assume a corresponding global variable exists and use that instead.
31-
// This is important because it allows us to avoid bundling all of our
32-
// dependencies, which allows browsers to cache those libraries between builds.
33-
externals: resolveExternals(isDevelopment, true),
34-
3534
module: {
36-
rules: resolveModuleRules(isDevelopment),
35+
rules: resolveModuleRules(isDevelopment, true),
3736
},
3837

39-
plugins: resolvePlugins(isDevelopment, version),
38+
plugins: resolvePlugins(isDevelopment, true, version),
4039
};
4140

4241
export default webpackConfig;

0 commit comments

Comments
 (0)