Giter Club home page Giter Club logo

nx-strapi-with-libraries-example's Introduction

Making Strapi work with nx libraries

What is this about?

This repo includes an example setup to get Strapi to work with nx libraries.

When starting the project, you can see the log

Strapi is starting: bar

to demonstrate server-side import of nx libraries and

The example plugin is running: bar

to demonstrate the import inside of a admin panel plugin.

More information about the issue at hand can be found in this Github issue.

There are a few issues when trying to get this to work, mainly because Strapi expects a specific folder structure to exist at various points during the build time and during runtime.

I've decided to create scripts to get this to work with an nx setup. One is responsible for serving the project locally, one is to build it and one to run the built output in production.

More on the scripts below.


There are two key components to get Strapi to work with nx libraries:

1. Handle the new folder structure due to the compiled libraries

Before, the dist folder looked like this:

dist/
├─ src/ (server-side code)
├─ config/ (various config files)
├─ build/ (admin panel)

Now, since we include the libraries, this folder structure changes to:

dist/
├─ packages/
│  ├─ my-app/
│  │  ├─ src/ (server-side code)
│  │  ├─ config/ (various config files)
│  │  ├─ build/ (admin panel)
│  ├─ my-lib/

This needs to be accounted for in various places, e.g. when resolving local plugins:

// config/plugins.ts
// ...
    'my-plugin': {
      enabled: true,
      resolve: `./${isRunningInServeMode ? '' : 'packages/my-app/'}src/plugins/my-plugin`,
    },
// ...

2. Use of tsconfig-paths

I'm making heavy use of the tsconfig-paths plugin in order to make the imports of the nx libraries map to the respective files. It will patch the require() calls to resolve the nx library imports to their actual files. This is needed as the compiled code of Strapi will still include imports such as require('@my-project/my-lib') that need to be resolved to the correct library.

For admin panel plugins to access nx libraries, we need to include the tsconfig-paths-webpack-plugin plugin in the admin webpack configuration.

// packages/my-app/src/admin/webpack.config.js
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

module.exports = (config, webpack) => {
  config.resolve.plugins = [
    new TsconfigPathsPlugin({
      configFile: 'tsconfig.base.json',
      baseUrl: process.env.NODE_ENV === 'production' ? 'dist/packages/cms' : 'packages/cms/dist',
      extensions: ['.ts', '.js'],
    }),
  ];
  return config;
};

⚠️Important note: Make sure that the path entries in your base TS config don't use a file extension such as .ts. Because the transpiled files will end in .js, those imports will fail!

Simply omit the extension, e.g.:

// tsconfig.base.json
"@my-project/shared/example": ["packages/shared/src/example.ts"] // fails
"@my-project/shared/example": ["packages/shared/src/example"]    // works

We also need to update the tsconfig files for both the admin panel as well as the server-side one. They need to extend our base tsconfig file that includes our paths options resolving to our libraries.

// packages/my-app/tsconfig.json
{
  // We need to extend our base tsconfig file
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    // "outDir": "dist",
    // add all other compilerOptions from https://github.com/strapi/strapi/blob/main/packages/utils/typescript/tsconfigs/server.json
    // ...
  },
}
// packages/my-app/src/admin/tsconfig.json
{
  // We need to extend our base tsconfig file
  "extends": "../../../../tsconfig.base.json",
  "compilerOptions": {
    // "module": "ES2020",
    // add all other compilerOptions from https://github.com/strapi/strapi/blob/main/packages/utils/typescript/tsconfigs/admin.json
    // ...
  },
}

Scripts to serve, build and start (a production build)

To serve and build the project using the local script, I updated the project configuration:

// packages/my-app/project.json
// ...
"targets": {
  "serve": {
    "executor": "nx:run-commands",
    "options": {
      "command": "node packages/my-app/scripts/serve.js",
      "envFile": "packages/my-app/.env"
    }
  },
  "build": {
    "executor": "nx:run-commands",
    "options": {
      "command": "node packages/my-app/scripts/build.js",
      "envFile": "packages/my-app/.env"
    }
  }
}
// ...

Running in production

A few things need to copied to the dist folder dist/packages/my-app (in my case, this is done in a Dockerfile):

  • /tsconfig.base.json -> dist/packages/my-app/tsconfig.base.json (required for the tsconfig-paths plugin to work)
  • packages/my-app/src/plugins/my-plugin/strapi-server.js -> dist/packages/my-app/packages/my-app/src/plugins/my-plugin/strapi-server.js (omitted during build)
  • packages/my-app/assets -> dist/packages/my-app/assets
  • packages/my-app/database -> dist/packages/my-app/database
  • packages/my-app/public -> dist/packages/my-app/public
  • packages/my-app/favicon.ico -> dist/packages/my-app/favicon.ico
  • packages/my-app/package.json -> dist/packages/my-app/package.json
  • A custom script that acts as the entrypoint for the app (see the script snippet start.js above)

Caveats:

  • I haven't figured out how to make the Strapi app restart upon a file being changed
  • I haven't figured out how to properly run the admin panel in watch mode

nx-strapi-with-libraries-example's People

Contributors

florianmrz avatar

Stargazers

 avatar

Watchers

 avatar

nx-strapi-with-libraries-example's Issues

Build issue

I'm trying to understand how to add Strapi into an nx project, thank you for this elaborate example!
However, when I run npx nx run strapi:develop from the root folder, i get an error Error: ENOENT: no such file or directory, stat 'tsconfig.base.json'. Any idea what might cause it?..

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.