brawaru / unplugin

Transform files containing ICU MessageFormat messages.

Home Page:https://npm.im/@vintl/unplugin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

@vintl/unplugin

Transform files containing ICU MessageFormat messages.

Summary

This Unplugin plugin adds a transform hook that pre-parses all messages in the JSON file into an AST that can be used at runtime without the need to bring in a parser, allowing the bundle size to be reduced. Read more about how this works on the Format.JS website →

Installation

With package manager of your choice:

npm

npm i -D @vintl/unplugin

yarn

yarn add -D @vintl/unplugin

pnpm

pnpm i -D @vintl/unplugin

Usage

Rollup

In your Rollup file, import icuMessages from @vintl/unplugin/rollup and then use it as a function in your plugins config array.

Example configuration:

import { defineConfig } from 'rollup'
import { plugin as icuMessages } from '@vintl/unplugin/rollup'

export default defineConfig({
  input: './src/index.mjs',
  output: { dir: './dist' },
  plugins: [
    icuMessages({
      include: './i18n/*.json',
      format: 'crowdin',
    }),
  ],
})

Vite

Similar to Rollup, import icuMessages from @vintl/unplugin/vite and then use it as a function in your plugins:

import { defineConfig } from 'vite'
import { plugin as icuMessages } from '@vintl/unplugin/vite'

export default defineConfig({
  // ...
  plugins: [
    icuMessages({
      include: './i18n/*.json',
      format: 'crowdin',
    }),
  ],
})

Webpack

Use require with @vintl/unplugin/webpack, destructure icuMessages from it, and use it as a function in your plugins:

const { icuMessages } = require('@vintl/unplugin/webpack')

module.exports = {
  // ...
  plugins: [
    icuMessages({
      include: './i18n/*.json',
      format: 'crowdin',
    }),
  ],
}

Other bundlers

Other bundlers are not really supported, but should generally work to capacity allowed by Unplugin.

Configuring plugin

List of all options

PluginOptions

include

  • Type: FilterPattern
  • Default: "**/*.messages.json"

Defines a string or regular expression, or an array of those, that should match with the file ID in order for it to be transformed.

exclude

  • Type: FilterPattern

Defines either a single glob string or regular expression, or an array of those, specifying which file IDs should NOT be transformed.

filter

  • Type: (id: string) => boolean | null | undefined | void

Custom filter function that checks whether the file must be transformed by the plugin.

indent

  • Type: string | number
  • Default: "\t"

Indentation used in the output file. Either a string or a number of spaces.

format

  • Type: CompileFn | string
  • Default: "default"

Either a name of the built-in formatter or function that accepts JSON object from the file and produces a record of messages keyed by their IDs.

parse

  • Type: (code: string, id: string) => void
  • Default: (code) => JSON.parse(code)

This function accepts file contents and parses it to a JavaScript value that will be passed to the format function (or resolved built-in formatter).

parserOptions

  • Type: MessagesParserOptionsValue
  • Default: localeFromModuleId

An object whose keys are message IDs and whose values are either parsing options for those messages or a resolver function that generates parsing options based on contextual information (such as module ID, message ID, and all messages).

pluginsWrapping

  • Type: boolean | WrappingOptions<PluginType>
  • Default: false

Plugins wrapping enables additional hooks in compatible bundlers to prevent other plugins from transforming files that would be transformed by this plugin.


WrappingOptions

use

  • Type: boolean
  • Default: false

Whether to enable the plugin wrapping.

extendDefaults

  • Type: boolean
  • Default: true

Whether to extend the defaults with provided wrappers or overwrite them.

wrappers

  • Type: WrappingFunctionsMap<PluginType>

A map of wrapping functions that can be used to modify the behavior of plugins. The map is an object where each key is a plugin name and the value is a function that accepts a plugin object and a filter function, and mutates the plugin hooks to use the provided filter function.

Usage with other plugins

If your configuration includes a plugin that handles JSON or other files that may conflict with this plugin, you have a few options to resolve the conflict:

  • Configure this plugin to include files with other extensions and store your messages in .messages files instead. To do this, change the options.include setting to **/*.messages.

  • Configure the conflicting plugin to exclude files processed by this plugin. For example, if you're using Rollup JSON, you can use its exclude option and set it to */i18n/*.json.

If the option to exclude files is not available in your environment (e.g. vitejs/vite#12168), you can enable the ‘plugins wrapping’ option by setting pluginsWrapping to true or { use: true }. This is only supported when using Vite or Rollup.

Example configuration
import { defineConfig } from 'rollup'
import json from '@rollup/plugin-json'
import { icuMessages } from '@braw/rollup-plugin-icu-messages/rollup'

export default defineConfig({
  input: './src/index.mjs',
  output: { dir: './dist' },
  plugins: [
    json(),
    icuMessages({
      include: './i18n/*.json',
      format: 'crowdin',
      pluginsWrapping: {
        use: true,
        extendDefaults: true, // <- @rollup/plugin-json is wrapped by default
        wrappers: {
          'my-json-plugin'(plugin, filter) {
            // implement plugin wrapping here
            // use filter function to check if a particular file is handled by icuMessages plugin
          },
        },
      },
    }),
  ],
})

Acknowledgements

This plugin is powered by icu-messageformat-parser by FormatJS.

Credits

Made with 💜 by Brawaru. Released under MIT Licence.

Support me by donating

About

Transform files containing ICU MessageFormat messages.

https://npm.im/@vintl/unplugin

License:MIT License


Languages

Language:TypeScript 100.0%