breaking: Standalone builds (#9496)
Fixes: FRMW-2742
In this PR, we fix the build output of the backend source code, which eliminates a lot of magic between the development and production environments.
Right now, we only compile the source files from the `src` directory and write them within the `dist` directory.
**Here's how the `src` directory with a custom module looks like**
```
src
├── modules
│ └── hello
│ ├── index.ts
```
**Here's the build output**
```
dist
├── modules
│ └── hello
│ ├── index.js
```
Let's imagine a file at the root of your project (maybe the `medusa-config.js` file) that wants to import the `modules/hello/index` file. How can we ensure that the import will work in both the development and production environments?
If we write the import targeting the `src` directory, it will break in production because it should target the `dist` directory.
## Solution
The solution is to compile everything within the project and mimic the file structure in the build output, not just the `src` directory.
**Here's how the fixed output should look like**
```
dist
├── src
│ ├── modules
│ │ └── hello
│ │ ├── index.js
├── medusa-config.js
├── yarn.lock
├── package.json
```
If you notice carefully, we also have `medusa-config.js`, `yarn.lock`, and `package.json` within the `dist` directory. We do so to create a standalone built application, something you can copy/paste to your server and run without relying on the original source code.
- This results in small containers since you are not copying unnecessary files.
- Clear distinction between the development and the production code. If you want to run the production server, then `cd` into the `dist` directory and run it from there.
## Changes in the PR
- Breaking: Remove the `dist` and `build` folders. Instead, write them production artefacts within the `.medusa` directory as `.medusa/admin` and `.medusa/server`.
- Breaking: Change the output of the `.medusa/server` folder to mimic the root project structure.
- Refactor: Remove `Symbol.for("ts-node.register.instance")]` check to find from where to load the source code.
- Refactor: Use `tsc` for creating the production build. This ensures we respect `tsconfig` settings when creating the build and also perform type-checking.
Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
export default {}
|
||||
@@ -0,0 +1 @@
|
||||
export default {}
|
||||
@@ -3,13 +3,15 @@ import { ModulesDefinition } from "../../definitions"
|
||||
import { MODULE_RESOURCE_TYPE, MODULE_SCOPE } from "../../types"
|
||||
import { registerMedusaModule } from "../register-modules"
|
||||
|
||||
const RESOLVED_PACKAGE = "@medusajs/test-service-resolved"
|
||||
jest.mock("resolve-cwd", () => jest.fn(() => RESOLVED_PACKAGE))
|
||||
const testServiceResolved = require.resolve(
|
||||
"../__fixtures__/test-service-resolved"
|
||||
)
|
||||
const defaultTestService = require.resolve("../__fixtures__/test-service")
|
||||
|
||||
describe("module definitions loader", () => {
|
||||
const defaultDefinition: ModuleDefinition = {
|
||||
key: "testService",
|
||||
defaultPackage: "@medusajs/test-service",
|
||||
defaultPackage: defaultTestService,
|
||||
label: "TestService",
|
||||
isRequired: false,
|
||||
defaultModuleDeclaration: {
|
||||
@@ -51,6 +53,7 @@ describe("module definitions loader", () => {
|
||||
|
||||
it("Resolves a custom module without pre-defined definition", () => {
|
||||
const res = registerMedusaModule("customModulesABC", {
|
||||
resolve: testServiceResolved,
|
||||
options: {
|
||||
test: 123,
|
||||
},
|
||||
@@ -58,7 +61,7 @@ describe("module definitions loader", () => {
|
||||
|
||||
expect(res).toEqual({
|
||||
customModulesABC: expect.objectContaining({
|
||||
resolutionPath: "@medusajs/test-service-resolved",
|
||||
resolutionPath: testServiceResolved,
|
||||
definition: expect.objectContaining({
|
||||
key: "customModulesABC",
|
||||
label: "Custom: customModulesABC",
|
||||
@@ -146,7 +149,7 @@ describe("module definitions loader", () => {
|
||||
|
||||
expect(res[defaultDefinition.key]).toEqual(
|
||||
expect.objectContaining({
|
||||
resolutionPath: RESOLVED_PACKAGE,
|
||||
resolutionPath: defaultTestService,
|
||||
definition: defaultDefinition,
|
||||
options: {},
|
||||
moduleDeclaration: {
|
||||
@@ -172,7 +175,7 @@ describe("module definitions loader", () => {
|
||||
|
||||
expect(res[defaultDefinition.key]).toEqual(
|
||||
expect.objectContaining({
|
||||
resolutionPath: RESOLVED_PACKAGE,
|
||||
resolutionPath: defaultTestService,
|
||||
definition: defaultDefinition,
|
||||
options: {},
|
||||
moduleDeclaration: {
|
||||
@@ -221,7 +224,7 @@ describe("module definitions loader", () => {
|
||||
|
||||
expect(res[defaultDefinition.key]).toEqual(
|
||||
expect.objectContaining({
|
||||
resolutionPath: RESOLVED_PACKAGE,
|
||||
resolutionPath: defaultTestService,
|
||||
definition: defaultDefinition,
|
||||
options: { test: 123 },
|
||||
moduleDeclaration: {
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
isString,
|
||||
normalizeImportPathWithSource,
|
||||
} from "@medusajs/utils"
|
||||
import resolveCwd from "resolve-cwd"
|
||||
import { ModulesDefinition } from "../definitions"
|
||||
import { MODULE_RESOURCE_TYPE, MODULE_SCOPE } from "../types"
|
||||
|
||||
@@ -68,7 +67,7 @@ function getCustomModuleResolution(
|
||||
const originalPath = normalizeImportPathWithSource(
|
||||
(isString(moduleConfig) ? moduleConfig : moduleConfig.resolve) as string
|
||||
)
|
||||
const resolutionPath = resolveCwd(originalPath)
|
||||
const resolutionPath = require.resolve(originalPath)
|
||||
|
||||
const conf = isObject(moduleConfig)
|
||||
? moduleConfig
|
||||
@@ -143,7 +142,7 @@ function getInternalModuleResolution(
|
||||
const originalPath = normalizeImportPathWithSource(
|
||||
(isString(moduleConfig) ? moduleConfig : moduleConfig.resolve) as string
|
||||
)
|
||||
resolutionPath = resolveCwd(originalPath)
|
||||
resolutionPath = require.resolve(originalPath)
|
||||
}
|
||||
|
||||
const moduleDeclaration = isObj ? moduleConfig : {}
|
||||
|
||||
Reference in New Issue
Block a user