atls-lab / frontend

Frontend testing repo - tools, frameworks, architecture.
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Переезд на `NextJS@latest` #1

Closed Nelfimov closed 9 months ago

Nelfimov commented 9 months ago

С чем связан запрос на фичу?

Необходимо найти способ успешного билда приложения на NextJS@latest.

Расскажите как вы это себе видите

Definition of done (критерий готовности)

Приложение билдится, запускается как в дев так и в прод режимах.

Приложите пример реализаций

No response

Приложите материалы задачи

No response

FrankJaskon commented 9 months ago

@Nelfimov

В дев режиме приложение запускается. Но корректно не билдится.

Пробовал на последней 13-той и 14-той версиях, билд в standalone режиме выполняется, но не создаёт необходимой структуры.

Он просто копирует локальные пакеты в standalone и dist папки и всё. Если в этих же зависимостях вернуться к версии 12.3.4, то билд проходит нормально, build start выполняется.

Создал минимальную структуру:

app
  entrypoints
    renderer
  fragments
  pages
ui
Структура 12.3.4 ![12 3 4_dist](https://github.com/atls-lab/frontend/assets/84450082/eab86e99-853c-4195-9f23-ec9e342340f3)
Структура 14.1.0 ![14 1 0_dist](https://github.com/atls-lab/frontend/assets/84450082/c40076d4-6d0a-4a80-80f9-624671928888)
next.config.js ``` module.exports = { experimental: { externalDir: true, swcFileReading: false, workerThreads: true, esmExternals: 'loose', }, output: 'standalone' } ```
tsconfig.json ``` { "compilerOptions": { "lib": [ "dom", "dom.iterable", "esnext" ], "allowJs": true, "skipLibCheck": true, "strict": false, "noEmit": true, "incremental": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", "target": "es5", "forceConsistentCasingInFileNames": true }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx" ], "exclude": [ "node_modules" ] } } ```
Основной package.json ``` { "name": "template", "private": true, "license": "BSD 3-Clause", "workspaces": [ "app/**/*", "ui/**/*" ], "devDependencies": { "@atls/code-service": "0.0.24", "@atls/config-eslint": "0.0.11", "@atls/config-jest": "0.0.9", "@jest/core": "29.7.0", "@types/eslint": "8.56.2", "@types/jest": "29.5.11", "@types/node": "20.11.5", "eslint": "8.20.0", "husky": "8.0.3", "typescript": "5.2.2" }, "packageManager": "yarn@4.0.2" } ```
Nelfimov commented 9 months ago

Попробуй поэкспериментировать с next.config.js

Возможно что-то из наших опций поменяло свой апи.

Предлагаю начать с минимального output: standalone и идти дальше

Nelfimov commented 9 months ago

Так же попробуй без монорепозитория билд - страницы и фрагменты держи прямо в энтрипоинте.

Задача - понять чем мы отличаемся от стока что билд идет некорректно.

FrankJaskon commented 9 months ago

@Nelfimov

Попробуй поэкспериментировать с next.config.js Возможно что-то из наших опций поменяло свой апи. Предлагаю начать с минимального output: standalone и идти дальше

Пробовал.

externalDir: true,
workerThreads: true,
esmExternals: 'loose',

Без этих опций билд даже не запускался, т.к не видел импортируемых компонент.

swcFileReading: false - как я понял, устаревшая опция. В последней версии некста она уже не поддерживается.

Так же попробуй без монорепозитория билд - страницы и фрагменты держи прямо в энтрипоинте. Задача - понять чем мы отличаемся от стока что билд идет некорректно.

Вынес компоненты на верхний уровень, чтобы в проекте использовался только корневой package.json.

В этом случае билд проходит. standalone папка создаётся не в dist, а в .next и там нет index.js, зато в остальном структура папок нормальная и приложение запускается с server.js.

Структура .next ![next_folder](https://github.com/atls-lab/frontend/assets/84450082/6b0e5497-b211-412b-8ea2-6b49f4c1ce62)
FrankJaskon commented 9 months ago

@Nelfimov

В доке сказано, что outputFileTracingRoot по умолчанию считает корнем расположение конфига. Но, видимо, это не так. Т.к явно указать корень помогло.

Некст начал генерировать почти правильную структуру с следующим конфигом:

const path = require('path');

module.exports = {
    experimental: {
        externalDir: true,
        outputFileTracingRoot: path.join(__dirname, './'),
        esmExternals: 'loose',
    },
    output: 'standalone'
}

Нюанс только в том, что папка static генерируется не в dist а в .next/static. Если её вручную подложить в dist/src/.next, то всё запускается нормально с node dist/src/server.js

Запуск ![start](https://github.com/atls-lab/frontend/assets/84450082/4cfc2996-a325-49f7-8cc4-660b8f33d681)
Структура 14.1.0 ![14 1 0](https://github.com/atls-lab/frontend/assets/84450082/3fa103ff-9c95-4f0e-b4f8-4430228032b8)
Nelfimov commented 9 months ago

Посмотри наши билд скрипты в проектах. В standalone нужно вручную переносить некоторые папки, такие как static и public

FrankJaskon commented 9 months ago

@Nelfimov

Поправил скрипты. Добавил базовую тему, ui/layout с @atls-ui-parts/layout и identity-ентрипоинт.

yarn prepack - отрабатывает без ошибок, yarn start - запускается для каждого энтрипоинты, переменные темы применяются.

Скрипт на проверку билда отрабатывает нестабильно. Иногда выполняется с ошибками, иногда без. При этом файлы генерируются, yarn start отрабатывает в любом случае.

Также yarn check отрабатывает с ошибками. Все логи ниже, ПР с кодом - https://github.com/atls-lab/frontend/pull/3

Лог с ошибками ``` yarn workspaces foreach --all image pack --publish --tag-policy hash-timestamp --registry some [template]: Process started [template]: ➤ YN0000: Workspace template not allowed for package. [template]: ➤ YN0000: Done in 0s [template]: Process exited (exit code 0), completed in 0s 43ms [@app/renderer-entrypoint]: Process started [@app/renderer-entrypoint]: ➤ YN0000: Package workspace @app/renderer-entrypoint to /tmp/b39a351062b922154c2eb0fecaa8d1e9 [@app/renderer-entrypoint]: ➤ YN0036: Calling the "prepack" lifecycle script [@app/renderer-entrypoint]: ➤ YN0000: ┌ Resolution step [@app/renderer-entrypoint]: ➤ YN0001: │ Error: @app/home-page@workspace:0.0.1: Workspace not found (@app/home-page@workspace:0.0.1) [@app/renderer-entrypoint]: at bwe.getWorkspaceByDescriptor (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:214:4512) [@app/renderer-entrypoint]: at LV.getCandidates (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:140:124663) [@app/renderer-entrypoint]: at BCt.getCandidates (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:141:1663) [@app/renderer-entrypoint]: at BCt.getCandidates (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:141:1663) [@app/renderer-entrypoint]: at /home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:214:9908 [@app/renderer-entrypoint]: at Object.prettifyAsyncErrors (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:140:56455) [@app/renderer-entrypoint]: at en (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:214:9871) [@app/renderer-entrypoint]: at async Promise.allSettled (index 0) [@app/renderer-entrypoint]: at async Object.allSettledSafe (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:140:55255) [@app/renderer-entrypoint]: ➤ YN0000: └ Completed [@app/renderer-entrypoint]: ➤ YN0000: Failed with errors in 6s 898ms [@app/renderer-entrypoint]: Process exited (exit code 1), completed in 6s 938ms [@app/home-page]: Process started [@app/home-page]: ➤ YN0000: Workspace @app/home-page not allowed for package. [@app/home-page]: ➤ YN0000: Done in 0s 1ms [@app/home-page]: Process exited (exit code 0), completed in 0s 94ms [@identity/renderer-entrypoint]: Process started [@identity/renderer-entrypoint]: ➤ YN0000: Package workspace @identity/renderer-entrypoint to /tmp/b02e4644101edf4339bb41bede2e3a55 [@identity/renderer-entrypoint]: ➤ YN0036: Calling the "prepack" lifecycle script [@identity/renderer-entrypoint]: ➤ YN0000: ┌ Resolution step [@identity/renderer-entrypoint]: ➤ YN0001: │ Error: @identity/home-page@workspace:0.0.1: Workspace not found (@identity/home-page@workspace:0.0.1) [@identity/renderer-entrypoint]: at bwe.getWorkspaceByDescriptor (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:214:4512) [@identity/renderer-entrypoint]: at LV.getCandidates (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:140:124663) [@identity/renderer-entrypoint]: at BCt.getCandidates (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:141:1663) [@identity/renderer-entrypoint]: at BCt.getCandidates (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:141:1663) [@identity/renderer-entrypoint]: at /home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:214:9908 [@identity/renderer-entrypoint]: at Object.prettifyAsyncErrors (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:140:56455) [@identity/renderer-entrypoint]: at en (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:214:9871) [@identity/renderer-entrypoint]: at async Promise.allSettled (index 2) [@identity/renderer-entrypoint]: at async Object.allSettledSafe (/home/frank/projects/npm/.yarn/releases/yarn-remote.cjs:140:55255) [@identity/renderer-entrypoint]: ➤ YN0000: └ Completed [@identity/renderer-entrypoint]: ➤ YN0000: Failed with errors in 6s 993ms [@identity/renderer-entrypoint]: Process exited (exit code 1), completed in 7s 46ms [@identity/navbar-fragment]: Process started [@identity/navbar-fragment]: ➤ YN0000: Workspace @identity/navbar-fragment not allowed for package. [@identity/navbar-fragment]: ➤ YN0000: Done in 0s [@identity/navbar-fragment]: Process exited (exit code 0), completed in 0s 39ms [@identity/home-page]: Process started [@identity/home-page]: ➤ YN0000: Workspace @identity/home-page not allowed for package. [@identity/home-page]: ➤ YN0000: Done in 0s [@identity/home-page]: Process exited (exit code 0), completed in 0s 46ms [@ui/hello]: Process started [@ui/hello]: ➤ YN0000: Workspace @ui/hello not allowed for package. [@ui/hello]: ➤ YN0000: Done in 0s [@ui/hello]: Process exited (exit code 0), completed in 0s 31ms [@ui/layout]: Process started [@ui/layout]: ➤ YN0000: Workspace @ui/layout not allowed for package. [@ui/layout]: ➤ YN0000: Done in 0s 1ms [@ui/layout]: Process exited (exit code 0), completed in 0s 34ms [@ui/theme]: Process started [@ui/theme]: ➤ YN0000: Workspace @ui/theme not allowed for package. [@ui/theme]: ➤ YN0000: Done in 0s [@ui/theme]: Process exited (exit code 0), completed in 0s 38ms Done in 14s 317ms ```
Лог без ошибок ``` yarn workspaces foreach --all image pack --publish --tag-policy hash-timestamp --registry some [template]: Process started [template]: ➤ YN0000: Workspace template not allowed for package. [template]: ➤ YN0000: Done in 0s 1ms [template]: Process exited (exit code 0), completed in 0s 42ms [@app/renderer-entrypoint]: Process started [@app/renderer-entrypoint]: ➤ YN0000: Package workspace @app/renderer-entrypoint to /tmp/a01d84ebe2ce508bce261b2e1f25000d [@app/renderer-entrypoint]: ➤ YN0036: Calling the "prepack" lifecycle script [@app/renderer-entrypoint]: ➤ YN0036: Prepack script failed (exit code 1, logs can be found here: /tmp/xfs-f6718219/prepack.log); run yarn prepack to investigate [@app/renderer-entrypoint]: ➤ YN0000: Failed with errors in 5s 564ms [@app/renderer-entrypoint]: Process exited (exit code 1), completed in 5s 603ms [@app/home-page]: Process started [@app/home-page]: ➤ YN0000: Workspace @app/home-page not allowed for package. [@app/home-page]: ➤ YN0000: Done in 0s [@app/home-page]: Process exited (exit code 0), completed in 0s 41ms [@identity/renderer-entrypoint]: Process started [@identity/renderer-entrypoint]: ➤ YN0000: Package workspace @identity/renderer-entrypoint to /tmp/9cfa658c6b994d37843f05f09fa19f34 [@identity/renderer-entrypoint]: ➤ YN0036: Calling the "prepack" lifecycle script [@identity/renderer-entrypoint]: ➤ YN0036: Prepack script failed (exit code 1, logs can be found here: /tmp/xfs-9a110482/prepack.log); run yarn prepack to investigate [@identity/renderer-entrypoint]: ➤ YN0000: Failed with errors in 5s 638ms [@identity/renderer-entrypoint]: Process exited (exit code 1), completed in 5s 675ms [@identity/navbar-fragment]: Process started [@identity/navbar-fragment]: ➤ YN0000: Workspace @identity/navbar-fragment not allowed for package. [@identity/navbar-fragment]: ➤ YN0000: Done in 0s [@identity/navbar-fragment]: Process exited (exit code 0), completed in 0s 52ms [@identity/home-page]: Process started [@identity/home-page]: ➤ YN0000: Workspace @identity/home-page not allowed for package. [@identity/home-page]: ➤ YN0000: Done in 0s [@identity/home-page]: Process exited (exit code 0), completed in 0s 30ms [@ui/hello]: Process started [@ui/hello]: ➤ YN0000: Workspace @ui/hello not allowed for package. [@ui/hello]: ➤ YN0000: Done in 0s [@ui/hello]: Process exited (exit code 0), completed in 0s 34ms [@ui/layout]: Process started [@ui/layout]: ➤ YN0000: Workspace @ui/layout not allowed for package. [@ui/layout]: ➤ YN0000: Done in 0s [@ui/layout]: Process exited (exit code 0), completed in 0s 36ms [@ui/theme]: Process started [@ui/theme]: ➤ YN0000: Workspace @ui/theme not allowed for package. [@ui/theme]: ➤ YN0000: Done in 0s [@ui/theme]: Process exited (exit code 0), completed in 0s 35ms Done in 11s 554ms ✘ frank@frank-Legion-5-15IAH7H  ~/projects/npm   working ±  cat /tmp/xfs-9a110482/prepack.log # This file contains the result of Yarn calling the "prepack" lifecycle script inside a workspace ("/home/frank/projects/npm/identity/entrypoints/renderer") ⚠ Linting is disabled ▲ Next.js 14.1.0 - Experiments (use at your own risk): · externalDir · esmExternals · outputFileTracingRoot Checking validity of types ... Creating an optimized production build ... ✓ Compiled successfully Collecting page data ... Generating static pages (0/3) ... ✓ Generating static pages (3/3) Finalizing page optimization ... Collecting build traces ... Route (pages) Size First Load JS ┌ ○ / 9.1 kB 98.4 kB ├ /_app 0 B 89.3 kB └ ○ /404 182 B 89.5 kB + First Load JS shared by all 89.3 kB ```
Лог yarn check ``` YN0000: ┌ Format ➤ YN0000: └ Completed in 0s 327ms ➤ YN0000: Done in 0s 328ms ➤ YN0000: ┌ Typecheck ➤ YN0000: │ .yarn/__virtual__/@atls-ui-parts-layout-virtual-0ebe609d69/0/cache/@atls-ui-parts-layout-npm-0.0.11-2f5478b94d-5bbe392b24.zip/node_modules/@atls-ui-parts/layout/dist/box/box.component.d.ts ➤ YN0000: │ ➤ YN0000: │ Error: Cannot find module 'csstype' or its corresponding type declarations. ➤ YN0000: │ ➤ YN0000: │ ➤ YN0000: │ .yarn/__virtual__/@atls-ui-parts-layout-virtual-0ebe609d69/0/cache/@atls-ui-parts-layout-npm-0.0.11-2f5478b94d-5bbe392b24.zip/node_modules/@atls-ui-parts/layout/dist/box/box.component.d.ts ➤ YN0000: │ ➤ YN0000: │ Error: Cannot find module 'csstype' or its corresponding type declarations. ➤ YN0000: │ ➤ YN0000: │ ➤ YN0000: │ .yarn/__virtual__/@atls-ui-parts-layout-virtual-0ebe609d69/0/cache/@atls-ui-parts-layout-npm-0.0.11-2f5478b94d-5bbe392b24.zip/node_modules/@atls-ui-parts/layout/dist/column/column.component.d.ts ➤ YN0000: │ ➤ YN0000: │ Error: Cannot find module '@emotion/react' or its corresponding type declarations. ➤ YN0000: │ ➤ YN0000: │ ➤ YN0000: │ .yarn/__virtual__/@atls-ui-parts-layout-virtual-0ebe609d69/0/cache/@atls-ui-parts-layout-npm-0.0.11-2f5478b94d-5bbe392b24.zip/node_modules/@atls-ui-parts/layout/dist/column/column.component.d.ts ➤ YN0000: │ ➤ YN0000: │ Error: Cannot find module '@emotion/react' or its corresponding type declarations. ➤ YN0000: │ ➤ YN0000: │ ➤ YN0000: │ .yarn/__virtual__/@atls-ui-parts-layout-virtual-0ebe609d69/0/cache/@atls-ui-parts-layout-npm-0.0.11-2f5478b94d-5bbe392b24.zip/node_modules/@atls-ui-parts/layout/dist/row/row.component.d.ts ➤ YN0000: │ ➤ YN0000: │ Error: Cannot find module '@emotion/react' or its corresponding type declarations. ➤ YN0000: │ ➤ YN0000: │ ➤ YN0000: │ .yarn/__virtual__/@atls-ui-parts-layout-virtual-0ebe609d69/0/cache/@atls-ui-parts-layout-npm-0.0.11-2f5478b94d-5bbe392b24.zip/node_modules/@atls-ui-parts/layout/dist/row/row.component.d.ts ➤ YN0000: │ ➤ YN0000: │ Error: Cannot find module '@emotion/react' or its corresponding type declarations. ➤ YN0000: │ ➤ YN0000: │ ➤ YN0000: │ .yarn/__virtual__/next-virtual-be665aed48/0/cache/next-npm-14.1.0-a62036d298-1db512c5c8.zip/node_modules/next/dist/compiled/@vercel/og/types.d.ts ➤ YN0000: │ ➤ YN0000: │ Error: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Consider adding an extension to the import path. ➤ YN0000: │ ➤ YN0000: │ ➤ YN0000: │ .yarn/__virtual__/next-virtual-be665aed48/0/cache/next-npm-14.1.0-a62036d298-1db512c5c8.zip/node_modules/next/server.d.ts ➤ YN0000: │ ➤ YN0000: │ Error: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("next/dist/compiled/@vercel/og/types")' call instead. ➤ YN0000: │ ➤ YN0000: │ ➤ YN0000: │ .yarn/cache/seamless-scroll-polyfill-npm-2.3.4-7293f9afe0-9e0111481d.zip/node_modules/seamless-scroll-polyfill/lib/index.d.cts ➤ YN0000: │ ➤ YN0000: │ Error: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("./scroll.js")' call instead. ➤ YN0000: │ ➤ YN0000: │ ➤ YN0000: │ .yarn/cache/seamless-scroll-polyfill-npm-2.3.4-7293f9afe0-9e0111481d.zip/node_modules/seamless-scroll-polyfill/lib/index.d.cts ➤ YN0000: │ ➤ YN0000: │ Error: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("./scrollIntoView.js")' call instead. ➤ YN0000: │ ➤ YN0000: │ ➤ YN0000: │ .yarn/cache/seamless-scroll-polyfill-npm-2.3.4-7293f9afe0-9e0111481d.zip/node_modules/seamless-scroll-polyfill/lib/index.d.cts ➤ YN0000: │ ➤ YN0000: │ Error: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("./polyfill.js")' call instead. ➤ YN0000: │ ➤ YN0000: │ ➤ YN0000: └ Completed in 2s 537ms ➤ YN0000: Failed with errors in 2s 537ms ➤ YN0000: ┌ Lint ➤ YN0000: │ Cannot read properties of undefined (reading 'getTokens') ➤ YN0000: │ Occurred while linting /home/frank/projects/npm/ui/hello/src/hello.component.tsx:3 ➤ YN0000: │ Rule: "@typescript-eslint/no-empty-function" ➤ YN0000: │ ➤ YN0000: │ reportIfEmpty [worker eval]:312559:47 ➤ YN0000: │ ruleErrorHandler .yarn/cache/eslint-npm-8.20.0-6bbc377ff7-8f584db07b.zip/node_modules/eslint/lib/linter/linter.js:1114:28 ➤ YN0000: │ .yarn/cache/eslint-npm-8.20.0-6bbc377ff7-8f584db07b.zip/node_modules/eslint/lib/linter/safe-emitter.js:45:58 ➤ YN0000: │ Object.emit .yarn/cache/eslint-npm-8.20.0-6bbc377ff7-8f584db07b.zip/node_modules/eslint/lib/linter/safe-emitter.js:45:38 ➤ YN0000: │ NodeEventGenerator.applySelector .yarn/cache/eslint-npm-8.20.0-6bbc377ff7-8f584db07b.zip/node_modules/eslint/lib/linter/node-event-generator.js:297:26 ➤ YN0000: │ NodeEventGenerator.applySelectors .yarn/cache/eslint-npm-8.20.0-6bbc377ff7-8f584db07b.zip/node_modules/eslint/lib/linter/node-event-generator.js:326:22 ➤ YN0000: │ NodeEventGenerator.enterNode .yarn/cache/eslint-npm-8.20.0-6bbc377ff7-8f584db07b.zip/node_modules/eslint/lib/linter/node-event-generator.js:340:14 ➤ YN0000: │ CodePathAnalyzer.enterNode .yarn/cache/eslint-npm-8.20.0-6bbc377ff7-8f584db07b.zip/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js:795:23 ➤ YN0000: │ .yarn/cache/eslint-npm-8.20.0-6bbc377ff7-8f584db07b.zip/node_modules/eslint/lib/linter/linter.js:1149:32 ➤ YN0000: └ Completed in 1s 37ms ➤ YN0000: Failed with errors in 1s 37ms ```