Hi everyone just getti…

3 minute read

Hi everyone - just getting started with nx, look very promising! I’m trying to use it with a preact app (rather than react), but struggling to understand the builders. I’m assuming I need to use a custom builder, and tried something like this: "build": { "builder": "@nrwl/workspace:run-commands", "options": { "commands": [ { "command": "preact build --src apps/my-app/src --dest apps/my-app/dist" } ] } }, Which seems to work, but as soon as I add some shared code (e.g. import { Foobar } from ‘@my-org/ui’;) then it fails to resolve @my-org/ui ?

Responses:

I haven’t tried using preact in Nx. It could be that preact is using its own tsconfig.json file and isn’t respecting the aliases in the root tsconfig.json file.

If you’re using TypeScript, tsconfig-paths might be able to help you out: https://www.npmjs.com/package/tsconfig-paths

Ah, I’m using –jx so not using the tsconfig-paths…

We use the @nrwl/web:build. Preact doesn’t work out of the box with that builder, but it has the option of patching the configuration using the option architect.build.options.webpackConfig

We use that to add the preact/compat aliases and extra stuff

ok I will see if I can get that to work - and compare the output to the standard ‘preact build’… I might need to reinvent some wheels especially around the sw.js but I’ll see if I can get it all hooked up… thanks!

For example, all isn’t needed but it has a hotfix after the breaking change of using babel to compile typescript that broke one app, we did this:

```const WorkboxPlugin = require(‘workbox-webpack-plugin’); const path = require(‘path’);

module.exports = function test(config, _ctx) { config.resolve = config.resolve || {}; config.resolve.alias = config.resolve.alias || {}; config.resolve.alias.react = ‘preact/compat’; config.resolve.alias[‘react-dom’] = ‘preact/compat’; config.resolve.alias[‘create-react-class’] = ‘preact/compat/lib/create-react-class’;

for (let i = 0; i < config.module.rules[0].options.presets.length; i += 1) { const preset = config.module.rules[0].options.presets[i]; const presetName = Array.isArray(preset) ? preset[0] : preset; if (presetName.search(‘@babel/preset-typescript’) !== -1) { config.module.rules[0].options.presets[i] = [ ‘@babel/preset-typescript’, { jsxPragma: ‘h’ }, ]; } }

config.module.rules = [ { test: /.tsx?$/, exclude: /node_modules/, use: [ { loader: ‘ts-loader’, query: { transpileOnly: true, configFile: path.resolve(__dirname, ‘tsconfig.app.json’), }, }, ], }, …config.module.rules, ];

config.plugins = config.plugins || []; config.plugins.push( new WorkboxPlugin.GenerateSW({ // these options encourage the ServiceWorkers to get in there fast // and not allow any straggling “old” SWs to hang around clientsClaim: true, skipWaiting: true, }), );

return config; };```

And also the tsconfig.json was changed to use preact,

{ "extends": "../../tsconfig.json", "compilerOptions": { "jsx": "react", "allowJs": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "types": ["node", "jest"], "jsxFactory": "h" }, "include": ["**/*.ts", "**/*.tsx"] }

Then the workflow is the same as other apps, e.g. ng preact-app-name –prod –source-map

etc

thanks! I’ll have a play

it would be nice if you could just plug in any type of module in to nx though… and still have the lib module resolver work.

Yes. Maybe is possible to do it just with tsconfigs if the preact/compat isn’t required. This configuration was created when we were using older Nx versions and didn’t redo it besides fixing breaking changes in the monorepo tooling

yeah we don’t need preact/compat … going to dig a bit deeper and see what options we have here… i’d love to move a monorepo (I used to work at google and miss the tooling ;-))

FYI if anyone else comes across this, I found the easiest way to do this. Use @nrwl/workspace:run-commands to trigger the normal preact build: "builder": "@nrwl/workspace:run-commands", "options": { "commands": [ { "command": "preact build --config apps/my-app/preact.config.js --src apps/my-app/src --dest apps/my-app/dist" } ] },

and then ensure you have the alias set up for any lib inside the preact config:

```const path = require(‘path’);

export default (config, env, helpers) => {

config.resolve.alias = Object.assign(config.resolve.alias, { ‘@my-org/ui-kit$’: path.resolve(__dirname, ‘../../libs/ui-kit/src/index.js’)

});

};```

(using –js not typescript and thus not the tsconfig)

Updated: