Repository navigation
Version 9.0.0 rewrites every package in TypeScript and moves the toolchain to Node.js 24.15, Babel 8, webpack-dev-server 6 and type checking with the project's own tsc. The compilers resolve to typed results and reject with typed errors instead of exiting the process, the build output comes from a new reporter, @rockpack/codestyle adds strict typescript-eslint presets and rules that catch bugs, and generated projects get git hooks, knip and live reload for SSR.
Upgrading from 8.x: see the migration guide.
Added
- All packages (
@rockpack/babel,@rockpack/codestyle,@rockpack/compiler,@rockpack/starter,@rockpack/tester,@rockpack/utils) rewritten in TypeScript, with ESM and CommonJS builds (@rockpack/codestyleships ESM only) @rockpack/compiler:isomorphicCompiler({ frontend, backend, frontendCallback, backendCallback })takes the two confs and builds them with an explicit context; theIsomorphicCompilerOptionstype is exported@rockpack/compilervalidates every documented option before building,sourceCompilerincluded, and reports all problems at once with their paths, for exampleINVALID_CONFIG: html[1].template must be a string@rockpack/compilerexportsRockpackError(codesINVALID_CONFIG,INVALID_ENTRY,BUILD_FAILED,DTS_FAILED), theRockpackErrorCodetype and the public typesCompilerConf,HtmlPage,CompilerCallback,Collection,Mode,CompilerResultandIsomorphicCompilerResult@rockpack/compiler: themodulesandpluginscollections passed to the compiler callbacks are typed (Collection<RuleSetRule>,Collection<WebpackPluginInstance>);get(name)returns[]for a missing name@rockpack/compiler:ignoreoption (globs) for the per-fileesm/cjsbuilds and the generated declarations; the default skips*.spec.*,*.test.*,__fixtures__,__mocks__and__tests__@rockpack/compiler:cache: truecaches production builds on disk innode_modules/.cache/rockpack@rockpack/compiler:sourceCompiler({ watch: true })rebuilds the per-file formats and the declarations after every source change and resolves to a result withstop()@rockpack/compilerbuild reporter: a progress bar per compiler in a terminal (client and server rows in an isomorphic build), one summary line per build, every problem (syntax, missing module, TypeScript, ESLint, Stylelint, CSS) in one format, plain output without a terminal or in CI;progress: falseturns the bars off@rockpack/compiler: thenodejsoption is public (Node.js libraries), andHtmlPagehonorsinject,minifyandtemplateParameters(merged overversion)@rockpack/compilerpicks uppostcss.config.cjsandpostcss.config.mjsnext topostcss.config.js@rockpack/babelloadsrockpack.babel.js,.cjs,.mjsor.ts(the first one found, in that order) and uses the default export of an ES module config; it exports theBabelMergeContext,BabelMergeFunction,Framework,Modules,TypescriptOptionsandCreateBabelPresetsOptionstypes@rockpack/babel:typescript: { env: true }runs@babel/preset-envafter@babel/preset-typescript, somodules,isNodejsandcore-jsapply to TypeScript; the merge context hastypescriptEnv@rockpack/babel/plugins/import-extension: a Babel 7 and 8 plugin that gives relative imports the extension of a per-file build (mjs,cjs,js); the compiler and the Rockpack packages use it instead of the unmaintainedbabel-plugin-add-import-extension@rockpack/babeltest mode transformsimport.meta(for exampleimport.meta.urland a module-levelconst __filename = fileURLToPath(import.meta.url)) so ES module sources run under Jest's CommonJS transform@rockpack/codestyle:makeConfig({ ignoreFile, jest, react, tsconfig })overrides the detection of the ignore file, the Jest rules, React and the tsconfig; theMakeConfigOptionstype is exported@rockpack/codestylereads ignore patterns from a.eslintflatignorefile (eslint-config-flat-gitignore), searched fromprocess.cwd()upward, so one file at a monorepo root covers every package@rockpack/codestyleexports the shared Stylelint and Commitlint configs from@rockpack/codestyle/stylelint(stylelintConfig) and@rockpack/codestyle/commitlint(commitlintConfig); generated projects use them, so their presets no longer have to be hoisted next to the project@rockpack/codestylelints.mtsand.ctsfiles as TypeScript, turns off@import-lite/no-default-exportand@typescript-eslint/naming-conventionfor.d.tsfiles and allows non-kebab-case folder names inside__fixtures__@rockpack/tester:serialoption (one suite at a time, no cache),coverageoption (false, or{ collectCoverageFrom, reporters, thresholds }) and a defaultcollectCoverageFromthat counts every source file; the default coverage reporters addtext-summaryandlcov, andcollectCoverage,coverageReportersandreportersfrom the Jest config are respected@rockpack/testerruns only the specs matching the positional command-line arguments or thetestPathPatternsoption, and reads--watchfrom the command line whenwatchis not passed@rockpack/tester:esm: trueruns the specs as ES modules (no CommonJS transform, TypeScript treated as ESM) undernode --experimental-vm-modules, and explains the flag when it is missing;.mjsand.cjsspecs and modules are transformed like.js; relative./x.jsimports resolve to.tssources@rockpack/tsconfigshipstsconfig.node.json, a DOM-free variant for Node.js code@rockpack/utilsexportsreadPackageJson, thePackageJsontype,packageRoot(import.meta.url)and theisRecordandisStringguards@rockpack/utils:getModeandsetModeaccept{ argv, env }to read from (andsetModeto write to) instead of the process and return the mode typed as one of the given modes;getRootRequireDir(script?)takes the script path explicitly (defaults toprocess.argv[1])@rockpack/starter:--offlinewrites the dependency ranges fromversions.jsonwithout asking the registry and skips the update check (installing still needs the network);-y/--yesanswers the remaining questions with the defaults (csr, with tests)@rockpack/starter: boolean flags (--tests,--offline,--install/--no-install,--yarn) accepttrue/false/yes/no/1/0, a bare flag meanstrue;--helplists every flag- Generated projects check their dependencies with knip: a
lint:depsscript, run bylint, and aknipsection inpackage.jsonwith the entries of the template - Generated projects install git hooks with
simple-git-hooks(pre-commitlint-staged,commit-msgcommitlint,pre-pushtests) and get a.nvmrcwith the Node.js major the starter requires - Generated projects declare the packages they use directly:
typescript,@types/node(24, the Node.js major they run on),@types/jestwith tests,webpack(forwebpack/moduletypes) in csr projects
Changed
- Breaking: Node.js 24.15 or newer is required by every package and by the starter CLI, which also checks the minor version (Babel 8 needs 24.11;
eslint-plugin-package-jsonand a dependency ofeslint-plugin-regexpin@rockpack/codestyleneed 24.15) - Breaking: Babel 8 in every package (
@babel/core8 is ESM only): plugins added throughrockpack.babel.*must support Babel 8, and the Babel types areInputOptionsfrom@babel/core(createBabelPresetsandBabelMergeFunctionreturn them;@types/babel__coreis gone) - Breaking:
@rockpack/babelno longer includes@babel/plugin-proposal-pipeline-operator(Babel 8 removed theminimalproposal); install it and add it withproposal: 'hack'or'fsharp'inrockpack.babel.* @rockpack/babel: decorators keep the legacy semantics throughversion: 'legacy'(Babel 8 ignoreslegacy: true); core-js polyfills come frombabel-plugin-polyfill-corejs3(usage-global, same targets) instead of preset-env's removeduseBuiltIns; preset-react runs through@rockpack/babel/presets/react, which keeps JSX parsing off for.ts,.mtsand.ctsfiles as Babel 7 did@rockpack/babel: development builds use React'sjsxDEVruntime (preset-react 8 turnsdevelopmenton for thedevelopmentenv); production builds are unchanged@rockpack/babel:react-compiler-runtimeis an optional peer dependency (only needed on React 17 and 18)- Breaking:
frontendCompiler,backendCompilerandlibraryCompilerresolve to a typed result (CompilerResult:config,buildwithstatsandsuccess,dev-serverwithurlandstop(),watchwithstop()); an awaited production build now resolves after the build has finished, and the dev server result once it listens - Breaking:
isomorphicCompilerresolves to a result as well (buildwithstatsandsuccessonce both production builds have finished,watchin development withstop(), which closes webpack, the server nodemon runs and the live reload server); it resolved before the build finished - Breaking: the compilers no longer call
process.exiton invalid options: they log[rockpack] <code>: <message>, setprocess.exitCode = 1and reject with aRockpackError - Breaking: stricter option checks: values the compiler used to tolerate (for example
port: '3000') and anesm/cjsformat withoutsrcordist(insourceCompilerandlibraryCompiler) are rejected withINVALID_CONFIG; anesm/cjsdistthat is the project root, the sources or a folder holding them is refused before anything is deleted - Breaking: production builds finish by closing webpack and exit with code
1when webpack reports errors (they exited with0before);Ctrl+Cexits with130,SIGTERMwith143; unexpected errors are no longer swallowed - Breaking:
@rockpack/compileroutput changed:@nuxt/friendly-errors-webpack-pluginandwebpack-format-messagesare gone together with theDONE Compiled successfully,[COMPILE] 0:3 minutes,Compiled successfully!andFailed to compile.lines; the dev server URL is printed as› Starting server on <url>after the first build; the per-file builds report onesourcesline with a line per format, andThe distribution folder will be ...became› output: <file> - Breaking:
@rockpack/compilerlints during the build only withlint: true(it ran ESLint and Stylelint whenever it found their configs); with the option it also findseslint.config.ts/.mts/.ctsand every Stylelint config name, and Stylelint checks only the sources;eslintandstylelintare optional peer dependencies - Breaking:
@rockpack/compilerno longer ships a bundle analyzer: theanalyzeroption (now reported asINVALID_CONFIGwith a hint), the--analyzerflag,webpack-bundle-analyzerand@statoscope/webpack-pluginare removed; add the analyzer you want in the compiler callback - Breaking:
@rockpack/compilerruns webpack-dev-server 6 (Express 5, http-proxy-middleware 4, no SockJS, nospdy, no proxybypass); customdevServersettings from the callback may need changes - Breaking:
@rockpack/compilerchecks types with the project's owntsc(tsc --noEmit -p tsconfig.json, TypeScript 6 or 7) instead offork-ts-checker-webpack-plugin: the build reports whattsc --noEmitreports, now also syntax errors of files outside the bundle and tsconfig errors; the plugin entry isTypeCheckPlugin(wasForkTsCheckerPlugin); declarations are emitted by the sametscwith the module resolution of the project'stsconfig.json(the forcedmoduleResolution: "node"andbaseUrlare gone), and declaration errors fail the build withDTS_FAILED(they were silent) - Breaking:
@rockpack/compilerno longer installs@rockpack/codestyle,cross-env,moment,colors,asyncor the unusednull-loader,imports-loader,script-loader,svg-inline-loaderandarraybuffer-loader; projects that got them through the compiler must add them to their own dependencies - Breaking:
nameandlibraryare no longer part of the publicCompilerConf: every compiler set them itself @rockpack/compiler:FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,SideEffectsFlagPluginandNoEmitOnErrorsPluginare no longer in thepluginscollection; the optimization settings apply them@rockpack/compiler: an isomorphic development build extracts CSS to thestylespath like production (defaultcss/styles.css), and the isomorphic build honorsdebugin its output@rockpack/compiler: the isomorphic compiler starts the live reload server only in development, on the first free port from 35729; the live reload client loads from the host name of the page instead oflocalhost- Breaking:
@rockpack/codestylehas no built-in ignore list: without a.eslintflatignore(ormakeConfig({ ignoreFile })) build output, coverage and.d.tsfiles are linted - Breaking:
@rockpack/codestyleuses the typescript-eslintstrictTypeCheckedandstylisticTypeCheckedpresets (wasrecommended,stylisticandrecommendedTypeChecked) and addsprefer-readonlyandswitch-exhaustiveness-check; numbers are allowed in template literals, void arrow shorthands are allowed,||stays allowed for strings andno-dynamic-deleteis off - Breaking:
@rockpack/codestylerequirestypealiases instead ofinterface(@typescript-eslint/consistent-type-definitions), and@typescript-eslint/explicit-function-return-typeis an error instead of a warning - Breaking:
@rockpack/codestyleadds rules that catch bugs:eqeqeq(== nullallowed),@typescript-eslint/no-shadow, sonarjs bug detectors (no-identical-conditions,no-all-duplicated-branches,no-duplicated-branches,no-element-overwrite,no-ignored-return,no-use-of-empty-return-value,non-existent-operator,no-collection-size-mischeck,no-empty-collection,no-unthrown-error,no-gratuitous-expressions,reduce-initial-value), unicorn rules (error-message,prefer-type-error,prefer-number-properties,prefer-structured-clone,no-useless-spread,no-useless-promise-resolve-reject,no-thenable,no-instanceof-builtins,no-await-in-promise-methods,no-single-promise-in-promise-methods) and, in test files, a set ofeslint-plugin-jesterror rules (no-done-callback,no-conditional-expect,no-identical-title,no-standalone-expect,valid-title,valid-expect,no-focused-tests,no-disabled-testsand others) - Breaking:
@rockpack/codestyle: React projects lint their test files witheslint-plugin-testing-library(react preset) andeslint-plugin-jest-dom(recommended); the Jest, Testing Library and jest-dom rules apply to*.{spec,test}.{js,jsx,ts,tsx}(the Jest rules covered only*.spec.{ts,tsx}), andjest: falseleaves all three out - Breaking:
@rockpack/codestyleno longer exports its internalisStringhelper; importisStringfrom@rockpack/utils @rockpack/codestyleships only the ESM build;require('@rockpack/codestyle')loads it through Node.jsrequire(esm);eslint-plugin-jsonis replaced by@eslint/json@rockpack/codestyle/stylelint:stylelint-config-clean-order10 orderstop,right,bottomandleftafter the logicalinsetproperties,text-wrap-*aftertext-wrapandstroke-colorwith the SVG properties;stylelint --fixapplies the new order@rockpack/codestyle: Prettier 3.9 moves an arrow function with a return type onto the line of the call it is passed to, and typescript-eslint 8.70 reports type parameters that default to{}(no-generated-empty-object-type);eslint --fixapplies the formatting- Breaking:
@rockpack/testerruns suites in parallel with the Jest cache by default; passserial: truefor the previous one-by-one behaviour - Breaking:
@rockpack/tester:setupFiles,setupFilesAfterEnv,moduleFileExtensionsandtestPathIgnorePatternsfrom the Jest config extend the defaults instead of replacing them (the text-encoder polyfill stays); passreplaceArrays: truefor the old behaviour - Breaking:
@rockpack/tester:tester()returns a promise of Jest's results (undefinedwhen Jest could not run) and no longer callsprocess.exit; failures setprocess.exitCode = 1. Writevoid tester(...)inscripts.tests.mts(theno-floating-promiseslint rule asks for it) or await it - Breaking:
@rockpack/testerno longer loadsjest.extend.js/.cjsfrom the project root; pass that Jest config as the second argument,tester({}, { ... }) @rockpack/tester:jest.init.*andjest.setup.*are referenced by absolute paths in the folder of the test script, so the script also works when run from another folder; the values of--mode,--testNamePattern/-tand--config/-care no longer taken as spec path patterns;typescriptis no longer a runtime dependency- Breaking:
@rockpack/tsconfigturns onnoPropertyAccessFromIndexSignature(and statesuseUnknownInCatchVariables): read index signatures with brackets, for exampleprocess.env['API_URL'] - Breaking:
@rockpack/tsconfigno longer turns offstrictPropertyInitialization, sostrictchecks that class properties are initialized; the base config no longer setsoutDir, and only.,./tsconfig.json,./tsconfig.node.jsonand./package.jsoncan be imported from the package @rockpack/utilsreads--modewithout yargs and has no import-time side effects; thePackageJsontype haspeerDependenciesandenginesinstead ofemail- Breaking:
@rockpack/starterrejects a project name that is not a valid npm package name (for example with capitals or spaces) and exits with code1listing the problems;rockpack .lower-cases the folder name @rockpack/starterexits with code1on an unknown or empty--typeand on a non-boolean value of a boolean flag, and reports a project path that is a file; the update check compares versions with semver, works offline and is skipped with--mode=test@rockpack/startercan no longer be imported as a module (it only has therockpackCLI) and no longer ships type declarations- Generated projects run their build and test scripts with Node.js itself (
node scripts.build.mts,node scripts.tests.mts) instead oftsx, which is no longer installed; the scripts are.mts, so Node.js treats them as ES modules without a"type"inpackage.json - Generated components ship the UMD bundle and the type declarations only (the unpublished
lib/cjsandlib/esmbuilds are gone); the csr template putsreact-dom/clientinto the vendor bundle - Generated projects get
.gitignoreand.gitattributesalso inside an existing git repository or without git (onlygit initand the hooks are skipped);.gitignorecovers the library build (/lib) and the ssr frontend build (/public)
Fixed
@rockpack/compilerper-file builds (sourceCompiler,libraryCompileresm/cjs): asset imports such as./styles.cssor./data.jsonkeep their path (they got.mjs/.cjsappended), import attributes (with { type: 'json' }) are kept, a file wins over a folder of the same name (./bothloaded./both/index), and dynamicimport('./x')gets the extension too@rockpack/compiler: an ES module PostCSS config (export default) was loaded as its module namespace and its plugins were silently ignored@rockpack/compiler: a development build whose webpack config cannot be applied (a plugin throws) rejects withBUILD_FAILEDand the real error instead of a laterTypeError@rockpack/compiler: a library whose bundle has errors no longer builds theesm/cjssources and declarations as well, so the errors are reported once@rockpack/compiler: a project with.env.defaultsbut no.envgets its variables inlined; before, the browser bundle kept rawprocess.env.Xreferences@rockpack/compiler: production builds for Node.js (backendCompiler, the backend ofisomorphicCompiler,nodejslibraries) keepconsolecalls; they were dropped like in browser bundles, so server logs disappeared@rockpack/compiler: thebannerfile is published, banner placeholders are filled by name, and the banner and defaultindex.ejsare found from the package root;index.ejshas one viewport meta tag@rockpack/compiler:distContextis the dist folder whendistis a folder; the.wasmrule matches.wasmfiles; library source and declaration build errors fail the build instead of being swallowed@rockpack/compiler: the Babel pluginssourceCompileresolves at runtime are regular dependencies@rockpack/compiler: thevendoroption moves the listed modules intovendor.jsonly (the main entry nowdependOns it); before, they were bundled into both files@rockpack/compiler:isomorphicCompilerfails withINVALID_CONFIGwhen the frontend and the backend write to the same file (one bundle silently overwrote the other)@rockpack/compiler:sourceCompilerandlibraryCompilerno longer build anesm/cjsformat with empty paths, whose output cleanup deleted the project folder@rockpack/compilerkeeps no state onglobal(ISOMORPHIC,CONFIG_ONLY,LIVE_RELOAD_PORT,LIVE_RELOAD_SERVERare gone), and the plugin builders no longer change the passed conf (banner,global)@rockpack/compiler: watching builds ignore the folders they write (the output folders,node_modules/.cache); in an isomorphic build every emit and type check triggered more rebuilds of both compilers@rockpack/compiler: isomorphic live reload fires once nodemon has spawned the restarted server, and the client waits until that server answers before it reloads the page (it reloaded too early: on the connection error page or with the old server's markup)@rockpack/codestyle: theeslint-plugin-react-hooksrules (rules of hooks, exhaustive deps and the React Compiler rules) were dropped for React projects because the@eslint-reactpreset was spread over them; they are a block of their own now, and@eslint-react/rules-of-hooksis off because it reported the same problems@rockpack/codestylesetstsconfigRootDir, so one ESLint run over files under several tsconfig folders no longer fails with "multiple candidate TSConfigRootDirs"@rockpack/codestyle:require()failed withERR_PACKAGE_PATH_NOT_EXPORTEDbecause the CommonJS build required the ESM-only@eslint-react/eslint-plugin@rockpack/tester: when the tester was imported as an ES module and Jest ran with--experimental-vm-modules, style imports failed withexports is not defined; Jest now always gets the style and file stubs from the CommonJS build@rockpack/tester: undernode --experimental-vm-modulesJest loads.mjsfiles as ES modules, which failed withexports is not definedbecause the tester turned them into CommonJS;.mjsfiles now keepimport/exportthere@rockpack/tester:watchis always a boolean@rockpack/babel: an ES modulerockpack.babel.jswas merged as its module namespace, adding adefaultkey to the Babel options; a brokenrockpack.babel.*now prints the underlying error@rockpack/starter: an absolute--folderwas joined onto the current folder@rockpack/starter:-h/--helpand-v/--versionprint the Rockpack usage and version instead of the yargs defaults; a missing yarn is reported once without a stack trace, and a failed git hooks install warns- Generated components keep the peer dependency ranges (
"react": "19"); they were pinned to the exact latest version, which locked consumers to it, and they are no longer installed twice - Generated projects without tests have no failing
testscript, generated libraries have nolint:styles/format:stylesscripts, androckpack .names the project after the folder with or without a git repository (it wasappoutside git) - Generated libraries and components publish only their built files, and the component
typespath points at the emitted declarations; the example app of a library has its ownpackage.jsonagain (the template overwrote it with a broken one) - Generated projects: git hooks work with npm 9+ (husky's removed
set-script/addcommands are gone);formatandlintuse the chosen package manager - Generated ssr, component and library projects without tests no longer reference
jesttypes they do not install - Generated csr and ssr projects pass
valuetoUnheadProvider(theheadprop is deprecated), have nomain: index.js, and the csr build readspackage.jsonnext to its script - Generated ssr projects listen on
PORTfrom.env(the template shippedPORT=8888but always listened on4000), stop loading when a request fails, resolvebabel-loaderandbabel-jestthrough@rockpack/compilerand@rockpack/tester, and reload the browser page in development again: the template loadsdev-server.js, the live reload client the compiler builds - Generated projects: the tester setup reads
.env.testwithprocess.loadEnvFileinstead of importing the undeclareddotenv
Deprecated
libraryCompiler('MyLib', ...): pass{ name: 'MyLib' }(theLibraryCompilerOptionstype is exported). The string form keeps working until 10.0isomorphicCompiler(frontendCompiler(...), backendCompiler(...)): pass the confs instead,isomorphicCompiler({ frontend: {...}, backend: {...} }), moving each compiler's callback tofrontendCallback/backendCallback. The old form keeps working until 10.0@rockpack/babel: TypeScript withouttypescript: { env: true }(preset-env skipped for TypeScript);env: truebecomes the default in 10.0
Removed
- Breaking: generated projects have no
analyzerscript (the compiler has no analyzer any more) - The csr and ssr templates no longer ship the
FeatureCardandSpotlightSectioncomponents, which no page rendered - The SSR template no longer ships a
rockpack.babel.js(custom Babel config throughrockpack.babel.*is still supported by@rockpack/babel) and no longer depends on the unusedreact-router-dom