5

I have a YAML file with a few translations. I need to transform these files into a JSON file. I've tried using yaml-import-loader and json-loader but I get an error.

Here's my setup:

const ExtractTextPlugin = require('extract-text-webpack-plugin');

const extractEnglish = new ExtractTextPlugin('lang/en.js');

module.exports = {
  entry: [
    './src/locales/application.en.yml',
  ],
  output: {
    filename: 'english.js',
  },
  module: {
    strictExportPresence: true,
    rules: [
      {
        test: /\.en\.yml$/,
        use: extractEnglish.extract({
          use: [
            // { loader: 'json-loader' },
            {
              loader: 'yaml-import-loader',
              options: {
                output: 'json',
              },
            }],
        }),
      },
    ],
  },
  plugins: [
    extractEnglish,
  ],
};

And the error I get:

Users/xxx/Documents/Project/node_modules/extract-text-webpack-plugin/dist/index.js:188
            chunk.sortModules();
                  ^

TypeError: chunk.sortModules is not a function
    at /Users/xxx/Documents/Project/node_modules/extract-text-webpack-plugin/dist/index.js:188:19

Same error whether or not the json-loader is commented or not.

I really don't understand what is going wrong.

Versions: "webpack": "2.6.1", "extract-text-webpack-plugin": "^3.0.0", "json-loader": "^0.5.7",

Anthon
  • 69,918
  • 32
  • 186
  • 246
Got The Fever Media
  • 750
  • 1
  • 9
  • 27
  • Sorry, maybe wrong wording. I have files... in YAML... that I use for translation. Meaning that in there I have Key/Values where the key is an identifier, and the value is the actual translation. All files (`.en.yml`, `.es.yml`...) have the same keys, but different values. – Got The Fever Media Aug 03 '17 at 07:02
  • Your error is on a line of code you do not show. It seems like this line of code is part of the `extract-text-webpack-plugin`. So you seem to have hit an error in the module you use and should probably report it as a bug. You are unlikely to get help here unless one of the plugin devs comes along. – flyx Aug 03 '17 at 08:32

2 Answers2

7

Not sure if this will help your situation but I recently found a solution to my i18n loading problem. I do this to extract YAML into JSON files upfront as I use angular-translate and needed to load files dynamically and on-demand. I avoid extract-text-webpack-plugin and use only loaders: file-loader and yaml-loader.

First I setup the import of my .yaml files near the beginning of source (in my case a specific chain of import files for webpack to process)

 import "./i18n/en.user.yaml";

I updated webpack config to translate YAML to JSON and have it available to load dynamically (everything originates from my 'src' directory, hence the context):

 rules: [{
   test: /.\.yaml$/,
   use: [{
     loader: 'file-loader',
     options: {
       name: '[path][name].json',
       context: 'src'
      }
    },{
      loader: 'yaml-loader'
    }]
  }]

This will translate my yaml file(s) and export them to my public directory, in this case at '/i18n/en.user.json'.

Now when angular-translate uploads my configured i18n settings via $http on-demand, it already has the parsed YAML and avoids having to parse it with js-yaml (or similar) on the front end.

Steve Hynding
  • 1,799
  • 1
  • 12
  • 22
3

A relatively old question, but I found it while searching for a solution to the same problem, so I thought it worth to chip in.

If you're not really using translation files in your code (i.e. you never import and use them directly) then using a Webpack loader is not the most elegant solution (you'd be forced to import them just so that the loader could be triggered and perform the conversion).

An alternative would be to use the CopyWebpackPlugin instead: it supports a transform option, which takes a function receiving the content of the file as a Buffer.

With a YAML parser (like js-yaml) as an additional dependency, adding this to your Webpack configuration would work:

const yaml = require('js-yaml');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  // OTHER WEBPACK CONFIG HERE

  plugins: [
    new CopyWebpackPlugin({
      patterns: [
        {
          from: 'i18n/**/*',
          to: 'i18n/[name].json',
          transform(content) {
            return Buffer.from(
              JSON.stringify(
                yaml.load(content.toString('utf8'), {
                  schema: yaml.JSON_SCHEMA
                })
              ),
              'utf8'
            )
          }
        }
      ]
    })
  ]
}

The i18n folder in the above example would contain your .yml translations. The Copy plugin would load them, convert them to JSON, and save them in the output folder under i18n/ (as specified by the to option).

Chad Fawcett
  • 248
  • 3
  • 11
TataBlack
  • 510
  • 5
  • 10