Skip to content

Commit

Permalink
feat: change createMessagesDeclaration to also accept array for monor…
Browse files Browse the repository at this point in the history
…epo support (#1700)

Resolves: #1699

This change renames "createMessagesDeclaration" to
"createMessagesDeclarations" and changes the type to an array. Each
entry of the array will be used to create message declaration files.
Supporting multiple message files helps to use next-intl in monorepo
setups.

Since v4 is in beta, I renamed the property and removed support for a
single string. To me, clean types lead to cleaner code. If compatibility
is a more of a concern during the beta phase, I could not change the
property name and keep the support for single strings. Please let me
know.

---------

Co-authored-by: Jan Amann <jan@amann.work>
  • Loading branch information
felix-quotez and amannn authored Feb 5, 2025
1 parent c4c5986 commit ca3fcd5
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 24 deletions.
46 changes: 25 additions & 21 deletions packages/next-intl/src/plugin/createMessagesDeclaration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,35 @@ function runOnce(fn: () => void) {
fn();
}

export default function createMessagesDeclaration(messagesPath: string) {
const fullPath = path.resolve(messagesPath);

if (!fs.existsSync(fullPath)) {
throwError(
`\`createMessagesDeclaration\` points to a non-existent file: ${fullPath}`
);
}
if (!fullPath.endsWith('.json')) {
throwError(
`\`createMessagesDeclaration\` needs to point to a JSON file. Received: ${fullPath}`
);
}

// Keep this as a runtime check and don't replace
// this with a constant during the build process
const env = process.env['NODE_ENV'.trim()];

export default function createMessagesDeclaration(
messagesPaths: Array<string>
) {
// Next.js can call the Next.js config multiple
// times - ensure we only run once.
runOnce(() => {
compileDeclaration(messagesPath);
for (const messagesPath of messagesPaths) {
const fullPath = path.resolve(messagesPath);

if (!fs.existsSync(fullPath)) {
throwError(
`\`createMessagesDeclaration\` points to a non-existent file: ${fullPath}`
);
}
if (!fullPath.endsWith('.json')) {
throwError(
`\`createMessagesDeclaration\` needs to point to a JSON file. Received: ${fullPath}`
);
}

// Keep this as a runtime check and don't replace
// this with a constant during the build process
const env = process.env['NODE_ENV'.trim()];

compileDeclaration(messagesPath);

if (env === 'development') {
startWatching(messagesPath);
if (env === 'development') {
startWatching(messagesPath);
}
}
});
}
Expand Down
8 changes: 6 additions & 2 deletions packages/next-intl/src/plugin/createNextIntlPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ function initPlugin(
);
}

if (pluginConfig.experimental?.createMessagesDeclaration) {
const messagesPathOrPaths =
pluginConfig.experimental?.createMessagesDeclaration;
if (messagesPathOrPaths) {
createMessagesDeclaration(
pluginConfig.experimental.createMessagesDeclaration
typeof messagesPathOrPaths === 'string'
? [messagesPathOrPaths]
: messagesPathOrPaths
);
}

Expand Down
3 changes: 2 additions & 1 deletion packages/next-intl/src/plugin/types.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type PluginConfig = {
requestConfig?: string;
experimental?: {
createMessagesDeclaration?: string;
/** A path to the messages file that you'd like to create a declaration for. In case you want to consider multiple files, you can pass an array of paths. */
createMessagesDeclaration?: string | Array<string>;
};
};

0 comments on commit ca3fcd5

Please sign in to comment.