diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..19302a62 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + "version": "1.0.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Jest: current file", + "program": "${workspaceFolder}/node_modules/.bin/jest", + "args": ["${fileBasenameNoExtension}", "--config", "jest.config.ts"], + "console": "integratedTerminal", + "windows": { + "program": "${workspaceFolder}/node_modules/jest/bin/jest" + } + } + ] + } diff --git a/docs/swc/configure-build.md b/docs/swc/configure-build.md index 957fc5c5..6677acd4 100644 --- a/docs/swc/configure-build.md +++ b/docs/swc/configure-build.md @@ -48,7 +48,7 @@ import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs"; const targets = browserslistToSwc(); -export default defineBuildConfig(targets); +export const swcConfig = defineBuildConfig(targets); ``` ### `targets` @@ -76,7 +76,7 @@ import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs"; const targets = browserslistToSwc({ queries: ["extends @workleap/browserslist-config"] }) -export default defineBuildConfig(targets); +export const swcConfig = defineBuildConfig(targets); ``` Or load the closest `.browserslistrc` configuration file and convert the queries into SWC targets: @@ -92,7 +92,7 @@ import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs"; const targets = browserslistToSwc(); -export default defineBuildConfig(targets); +export const swcConfig = defineBuildConfig(targets); ``` The `browserslistToSwc(options)` utility function accepts any option supported by Browserslist [JS API](https://github.com/browserslist/browserslist#js-api) in addition to a `queries` option: @@ -117,7 +117,7 @@ import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs"; const targets = browserslistToSwc(); -export default defineBuildConfig(targets, { +export const swcConfig = defineBuildConfig(targets, { parser: "ecmascript" }); ``` @@ -154,7 +154,7 @@ function mangleMinifiedCode(config) { return config; } -export default defineBuildConfig(targets, { +export const swcConfig = defineBuildConfig(targets, { transformers: [mangleMinifiedCode] }); ``` diff --git a/docs/swc/configure-dev.md b/docs/swc/configure-dev.md index 8f9a0192..fc6ee028 100644 --- a/docs/swc/configure-dev.md +++ b/docs/swc/configure-dev.md @@ -48,7 +48,7 @@ import { browserslistToSwc, defineDevConfig } from "@workleap/swc-configs"; const targets = browserslistToSwc(); -export default defineDevConfig(targets); +export const swcConfig = defineDevConfig(targets); ``` ### `targets` @@ -76,7 +76,7 @@ import { browserslistToSwc, defineDevConfig } from "@workleap/swc-configs"; const targets = browserslistToSwc({ queries: ["extends @workleap/browserslist-config"] }); -export default defineDevConfig(targets); +export const swcConfig = defineDevConfig(targets); ``` Or load the closest `.browserslistrc` configuration file and convert the queries into SWC targets: @@ -92,7 +92,7 @@ import { browserslistToSwc, defineDevConfig } from "@workleap/swc-configs"; const targets = browserslistToSwc(); -export default defineDevConfig(targets); +export const swcConfig = defineDevConfig(targets); ``` The `browserslistToSwc(options)` utility function accepts any option supported by Browserslist [JS API](https://github.com/browserslist/browserslist#js-api) in addition to a `queries` option: @@ -117,7 +117,7 @@ import { browserslistToSwc, defineDevConfig } from "@workleap/swc-configs"; const targets = browserslistToSwc(); -export default defineDevConfig(targets, { +export const swcConfig = defineDevConfig(targets, { fastRefresh: false }); ``` @@ -136,7 +136,7 @@ import { browserslistToSwc, defineDevConfig } from "@workleap/swc-configs"; const targets = browserslistToSwc(); -export default defineDevConfig(targets, { +export const swcConfig = defineDevConfig(targets, { parser: "ecmascript" }); ``` @@ -173,7 +173,7 @@ function disableReactBuiltins(config) { return config; } -export default defineDevConfig(targets, { +export const swcConfig = defineDevConfig(targets, { transformers: [disableReactBuiltins] }); ``` diff --git a/docs/swc/configure-jest.md b/docs/swc/configure-jest.md index 55e076ab..2c8b04c3 100644 --- a/docs/swc/configure-jest.md +++ b/docs/swc/configure-jest.md @@ -49,7 +49,7 @@ Then, open the newly created file and export the SWC configuration by using the ```ts !#6-8 swc.jest.ts import { defineJestConfig } from "@workleap/swc-configs"; -export default defineJestConfig(); +export const swcConfig = defineJestConfig(); ``` ## 3. Set predefined options @@ -66,7 +66,7 @@ Whether or not to transform React code. ```ts !#4 swc.jest.ts import { defineJestConfig } from "@workleap/swc-configs"; -export default defineJestConfig({ +export const swcConfig = defineJestConfig({ react: true }); ``` @@ -81,7 +81,7 @@ Whether SWC should expect to parse JavaScript or TypeScript code. ```ts !#4 swc.jest.ts import { defineJestConfig } from "@workleap/swc-configs"; -export default defineJestConfig({ +export const swcConfig = defineJestConfig({ parser: "ecmascript" }); ``` @@ -114,7 +114,7 @@ const useCommonJsModules: SwcConfigTransformer = (config: SwcConfig) => { return config; }; -export default defineJestConfig({ +export const swcConfig = defineJestConfig({ transformers: [useCommonJsModules] }); ``` diff --git a/docs/webpack/configure-build.md b/docs/webpack/configure-build.md index f37bfe02..4ed131e1 100644 --- a/docs/webpack/configure-build.md +++ b/docs/webpack/configure-build.md @@ -29,6 +29,8 @@ npm install -D @workleap/webpack-configs webpack webpack-cli @swc/core @swc/help ## 2. Configure webpack +### HTML template + First, create a `public` folder with an `index.html` file at the root of the project: ``` !#2-3 @@ -56,6 +58,8 @@ Then, open the newly created `index.html` file and copy/paste the following cont The content of the `public/index.html` file is the default template that will be used by [HtmlWebpackPlugin](https://webpack.js.org/plugins/html-webpack-plugin/). +### defineBuildConfig + Next, create a configuration file named `webpack.build.js` at the root of the project: ``` !#5 @@ -77,7 +81,7 @@ import { swcConfig } from "./swc.build.js"; export default defineBuildConfig(swcConfig); ``` -### `swcConfig` +### swcConfig In the previous code sample, the `defineBuildConfig(swcConfig, options)` function receive an SWC [configuration object](https://swc.rs/docs/configuration/swcrc) through the `swcConfig` parameter. diff --git a/docs/webpack/configure-dev.md b/docs/webpack/configure-dev.md index bb9237df..45f5cd07 100644 --- a/docs/webpack/configure-dev.md +++ b/docs/webpack/configure-dev.md @@ -15,20 +15,22 @@ Open a terminal at the root of the project and install the following packages: +++ pnpm ```bash -pnpm add -D @workleap/webpack-configs webpack webpack-cli webpack-dev-server @swc/core @swc/helpers browserslist postcss +pnpm add -D @workleap/webpack-configs webpack webpack-cli webpack-dev-server @swc/core @swc/helpers browserslist postcss nodemon ``` +++ yarn ```bash -yarn add -D @workleap/webpack-configs webpack webpack-cli webpack-dev-server @swc/core @swc/helpers browserslist postcss +yarn add -D @workleap/webpack-configs webpack webpack-cli webpack-dev-server @swc/core @swc/helpers browserslist postcss nodemon ``` +++ npm ```bash -npm install -D @workleap/webpack-configs webpack webpack-cli webpack-dev-server @swc/core @swc/helpers browserslist postcss +npm install -D @workleap/webpack-configs webpack webpack-cli webpack-dev-server @swc/core @swc/helpers browserslist postcss nodemon ``` +++ ## 2. Configure webpack +### HTML template + First, create a `public` folder with an `index.html` file at the root of the project: ``` !#2-3 @@ -38,7 +40,6 @@ web-project ├── src ├──── ... ├── package.json -├── webpack.dev.js ``` Then, open the newly created `index.html` file and copy/paste the following content: @@ -56,10 +57,44 @@ Then, open the newly created `index.html` file and copy/paste the following cont The content of the `public/index.html` file is the default template that will be used by [HtmlWebpackPlugin](https://webpack.js.org/plugins/html-webpack-plugin/). +#### Adding local assets + +To link local assets such as a `favicon.png` in the default HTML template, it is recommended to preprend the **relative** path of every asset with the `publicPath` of the webpack config. + +First, add the asset to the `public` folder at the root of the project: + +``` !#4 +web-project +├── public +├──── index.html +├──── favicon.png +├── src +├──── ... +├── package.json +``` + +Then, add the assets to the `index.html` file: + +```html !#4 public/index.html + + +
+ + + + + + +``` + +### defineDevConfig + Next, create a configuration file named `webpack.dev.js` at the root of the project: -``` !#5 +``` !#7 web-project +├── public +├──── index.html ├── src ├──── ... ├── package.json @@ -77,7 +112,7 @@ import { swcConfig } from "./swc.dev.js"; export default defineDevConfig(swcConfig); ``` -### `swcConfig` +### swcConfig In the previous code sample, the `defineDevConfig(swcConfig, options)` function receive an SWC [configuration object](https://swc.rs/docs/configuration/swcrc) through the `swcConfig` parameter. @@ -415,17 +450,45 @@ Modifying a webpack configuration object can be an arduous task, to help with th [!ref Transformer utilities](transformer-utilities.md) -## 5. Add a CLI script +## 5. Setup nodemon + +[Nodemon](https://nodemon.io/) is a utility that will monitor for any changes in the `swc.dev.js` and `webpack.dev.dev.js` files and restart the webpack development server whenever a change occurs. + +First, add a `nodemon.json` file at the root of the project: + +``` !#8 +web-project +├── public +├──── index.html +├── src +├──── ... +├── package.json +├── webpack.dev.js +├── nodemon.json +``` + +Then, open the `nodemon.json` file and copy/paste the following content: + +```json nodemon.json +{ + "watch": ["swc.dev.js", "webpack.dev.js"], + "exec": "webpack serve --config webpack.dev.js" +} +``` + +Finally, add a CLI script at the [next step](#6-add-a-cli-script) of this guide. + +## 6. Add a CLI script To initiate the development server, add the following script to your project `package.json` file: ```json package.json { - "dev": "webpack serve --config webpack.dev.js" + "dev": "nodemon" } ``` -## 6. Set environment variables +## 7. Set environment variables To deal with environment variables, the webpack documentation suggests using the [--env option](https://webpack.js.org/guides/environment-variables/) from its CLI. While that would work, by using webpack `--env` CLI option, the environment variables would only be made available to the webpack configuration files (.e.g. `webpack.dev.js`) rather than any Node.js files. Therefore we **do not recommend** using webpack `--env` CLI option. @@ -435,7 +498,7 @@ We recommend instead to define environment variables using [cross-env](https://g ```json package.json { - "dev": "cross-env DEBUG=true webpack serve --config webpack.dev.js" + "dev": "cross-env DEBUG=true nodemon" } ``` @@ -492,8 +555,8 @@ export function App() { The `=== "true"` part of `"DEBUG": process.env.DEBUG === "true"` is very important, otherwise the environment variable value would be `"true"` instead of `true`. !!! -## 7. Try it :rocket: +## 8. Try it :rocket: -To test your new webpack configuration, open a terminal at the root of the project and execute the [CLI script added earlier](#5-add-a-cli-script). A development server should start without outputting any error in the terminal. +To test your new webpack configuration, open a terminal at the root of the project and execute the [CLI script added earlier](#6-add-a-cli-script). A development server should start without outputting any error in the terminal. diff --git a/packages/webpack-configs/src/build.ts b/packages/webpack-configs/src/build.ts index 7966df46..fd0fb25a 100644 --- a/packages/webpack-configs/src/build.ts +++ b/packages/webpack-configs/src/build.ts @@ -3,6 +3,7 @@ import HtmlWebpackPlugin from "html-webpack-plugin"; import MiniCssExtractPlugin from "mini-css-extract-plugin"; import { createRequire } from "node:module"; import path from "node:path"; +import { fileURLToPath } from "node:url"; import TerserPlugin from "terser-webpack-plugin"; import type { Configuration as WebpackConfig } from "webpack"; import webpack from "webpack"; @@ -17,6 +18,9 @@ const DefinePlugin = webpack.DefinePlugin; // is available const require = createRequire(import.meta.url); +// The equivalent of __filename for CommonJS. +const __filename = fileURLToPath(import.meta.url); + type MiniCssExtractPluginOptions = NonNullable