npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@vintl/unplugin

v2.0.0

Published

Transform files containing ICU MessageFormat messages.

Downloads

2,241

Readme

@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 { 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 { 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

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).

onParseError

A method to handle any errors that may arise during the parsing of one of the messages.

pluginsWrapping

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

output

Options that allow to configure the output of transformation.


ParseErrorHandlingOption

Either a name of the built-in handler, or a custom method that will accept context and may return the fallback result, throw another error, or return nothing (undefined) to ignore the error.

Custom methods can access the built-in handlers using the context's useBuiltinStrategy method and are used solely for logging.

The following built-in handlers exist:

| Name | Description | | ------------------------ | ------------------------------------------------ | | use-message-as-literal | Uses the unparsed message contents as a literal. | | use-id-as-literal | Uses the the message ID as a literal. | | use-empty-literal | Uses a literal with an empty string. | | skip | Ignore the error and skip the message. |


ParseErrorContext

A read-only object containing information relevant to the parsing error, including the error itself.

moduleId

  • Type: string

ID of the module that is being parsed.

messageId

  • Type: string

ID of the message that cannot be parsed.

message

  • Type: string

Message that cannot be parsed.

error

  • Type: unknown

Error that occurred during the parsing.

parserOptions

  • Type: ParserOptions | undefined

Parser options that were used to parse the message.

useBuiltinStrategy

  • Type: (name: ParseErrorHandlingStrategy) => MessageFormatElement[] | void

Method used to call one of the built-in error handling strategies and return its result.


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.


OutputOptions

Represents options for the transformation output.

format

  • Type: 'module' | 'json' | ((messages: MessagesASTMap | MessagesMap) => string)
  • Default: 'module'

Defines the format of the output file or provides a function that will encode input JavaScript object containing the messages into a string representing contents of the transformed file.

The following formats are supported:

| Name | Description | | :--------: | :------------------------------------------------------------ | | 'module' | Outputs an ESM JavaScript module. | | 'json' | Outputs a JSON string that can be processed by other plugins. |

You can also provide a custom function that accepts either a MessagesASTMap or a MessagesMap and returns a string.

type

  • Type: 'raw' | 'ast'
  • Default: 'ast'

Defines what kind of output should be generated.

The following output types are supported:

| Name | Description | | :-----: | :--------------------------------------------- | | 'raw' | Outputs the messages as is. | | 'ast' | Pre-parses the messages and outputs their AST. |

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.

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.