Add a New Solid Project
The code for this example is available on GitHub:
Example repository/nrwl/nx-recipes/tree/main/solidjs
Supported Features
Because we are not using an Nx plugin for Solid, there are a few items we'll have to configure manually. We'll have to configure our own build system. There are no pre-created Solid-specific code generators. And we'll have to take care of updating any framework dependencies as needed.
✅ Run Tasks ✅ Cache Task Results ✅ Share Your Cache ✅ Explore the Graph ✅ Distribute Task Execution ✅ Integrate with Editors ✅ Automate Updating Nx ✅ Enforce Module Boundaries 🚫 Use Code Generators 🚫 Automate Updating Framework Dependencies
Install Solid and Other Dependencies
❯
npm add solid-js
❯
npm add -D solid-devtools vite-plugin-solid
❯
nx add @nx/web
Create an Application
Directory Flag Behavior ChangesThe command below uses the as-provided directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the derived option, omit the --directory flag. See the as-provided vs. derived documentation for more details.
We'll start with a web application and then tweak the settings to match what we need. Add a new web application to your workspace with the following command:
❯
nx g @nx/web:app my-solid-app --directory=apps/my-solid-app --bundler=vite
The @nx/web:app generator will create some files that are unnecessary for our Solid application.
The files and folders to be deleted are:
- apps/my-solid-app/public/
- apps/my-solid-app/src/app/
- apps/my-solid-app/src/main.ts
- apps/my-solid-app/src/styles.css
- apps/my-solid-app/.babelrc
Turn the Application into a Solid Application
Now we'll create the files that are necessary to turn our application into a Solid application.
Add the following files
1import type { Component } from 'solid-js';
2
3const App: Component = () => {
4  return (
5    <div>
6      <header>
7        <p>
8          Edit <code>src/App.tsx</code> and save to reload.
9        </p>
10        <a
11          href="https://github.com/solidjs/solid"
12          target="_blank"
13          rel="noopener noreferrer"
14        >
15          Learn Solid Now
16        </a>
17      </header>
18    </div>
19  );
20};
21
22export default App;
231/* @refresh reload */
2import { render } from 'solid-js/web';
3
4import App from './App';
5
6const root = document.getElementById('root');
7
8if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
9  throw new Error(
10    'Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?'
11  );
12}
13
14render(() => <App />, root!);
15Update the following files
1
2<html lang="en">
3  <head>
4    <meta charset="utf-8" />
5    <meta name="viewport" content="width=device-width, initial-scale=1" />
6    <meta name="theme-color" content="#000000" />
7    <title>Solid App</title>
8  </head>
9  <body>
10    <noscript>You need to enable JavaScript to run this app.</noscript>
11    <div id="root"></div>
12
13    <script src="src/index.tsx" type="module"></script>
14  </body>
15</html>
161/// <reference types="vitest" />
2import { defineConfig } from 'vite';
3import solidPlugin from 'vite-plugin-solid';
4// import devtools from 'solid-devtools/vite';
5
6import viteTsConfigPaths from 'vite-tsconfig-paths';
7
8export default defineConfig({
9  cacheDir: '../../node_modules/.vite/apps/my-solid-app',
10
11  server: {
12    port: 3000,
13  },
14
15  build: {
16    target: 'esnext',
17  },
18
19  plugins: [
20    viteTsConfigPaths({
21      root: '../../',
22    }),
23    /*
24                                                                        Uncomment the following line to enable solid-devtools.
25                                                                        For more info see https://github.com/thetarnav/solid-devtools/tree/main/packages/extension#readme
26                                                                        */
27    // devtools(),
28    solidPlugin(),
29  ],
30
31  // Uncomment this if you are using workers.
32  // worker: {
33  //  plugins: [
34  //    viteTsConfigPaths({
35  //      root: '../../',
36  //    }),
37  //  ],
38  // },
39
40  test: {
41    globals: true,
42    cache: {
43      dir: '../../node_modules/.vitest/apps/my-solid-app',
44    },
45    environment: 'jsdom',
46    include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
47  },
48});
491{
2  "extends": "../../tsconfig.base.json",
3  "files": [],
4  "compilerOptions": {
5    "target": "ESNext",
6    "useDefineForClassFields": true,
7    "module": "ESNext",
8    "lib": ["ESNext", "DOM"],
9    "moduleResolution": "Node",
10    "jsx": "preserve",
11    "jsxImportSource": "solid-js",
12    "strict": true,
13    "resolveJsonModule": true,
14    "isolatedModules": true,
15    "esModuleInterop": true,
16    "noEmit": true,
17    "noUnusedLocals": true,
18    "noUnusedParameters": true,
19    "noImplicitReturns": true,
20    "skipLibCheck": true,
21    "types": ["vite/client", "vitest"]
22  },
23  "include": ["src"],
24  "references": [
25    {
26      "path": "./tsconfig.app.json"
27    },
28    {
29      "path": "./tsconfig.spec.json"
30    }
31  ]
32}
33You can now run nx serve my-solid-app and your Solid application can be viewed in your browser!
Create a Library
Directory Flag Behavior ChangesThe command below uses the as-provided directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the derived option, omit the --directory flag. See the as-provided vs. derived documentation for more details.
Let's create a library that our Solid application is going to consume. To create a new library, install the @nx/js package and run:
❯
nx g @nx/js:lib my-lib --directory=libs/my-lib
Once the library is created, update the following files.
Rename libs/my-lib/src/lib/my-lib.ts -> libs/my-lib/src/lib/my-lib.tsx, then edit the contents to:
1export function MyLibComponent(props: { name: string }) {
2  return <h1>Hello {props.name} from MyLib</h1>;
3}
41{
2  "extends": "../../tsconfig.base.json",
3  "compilerOptions": {
4    "module": "commonjs",
5    "forceConsistentCasingInFileNames": true,
6    "strict": true,
7    "noImplicitOverride": true,
8    "noPropertyAccessFromIndexSignature": true,
9    "noImplicitReturns": true,
10    "noFallthroughCasesInSwitch": true,
11    "jsx": "preserve",
12    "jsxImportSource": "solid-js",
13    "types": ["vitest"]
14  },
15  "files": [],
16  "include": [],
17  "references": [
18    {
19      "path": "./tsconfig.lib.json"
20    },
21    {
22      "path": "./tsconfig.spec.json"
23    }
24  ]
25}
261import type { Component } from 'solid-js';
2import { MyLibComponent } from '@acme/my-lib';
3
4const App: Component = () => {
5  return (
6    <div>
7      <header>
8        <p>
9          Edit <code>src/App.tsx</code> and save to reload.
10        </p>
11        <MyLibComponent name={'there'} />
12        <a
13          href="https://github.com/solidjs/solid"
14          target="_blank"
15          rel="noopener noreferrer"
16        >
17          Learn Solid Now
18        </a>
19      </header>
20    </div>
21  );
22};
23
24export default App;
25Now when you serve your application, you'll see the content from the library being displayed.