import yaml via webpack into typescript

Viewed 6150

Is there a way to import Yaml into Typescript file via Webpack without errors?

// webpack config

const path = require('path');

module.exports = {
  entry: './src/index.ts',
  mode: 'production',
  module: {
    rules: [
      {
        test: /\.yaml$/,
        use: 'yaml',
      },
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'index.js',
    path: path.resolve(__dirname, 'dist'),
    libraryTarget: 'commonjs',
  },
};
// package.json
"devDependencies": {
    "yaml-ts-loader": "^1.0.0",
.....

in test.ts file

import examples from './test-examples.yaml';

describe('', () => {...})

results in

TSError: ⨯ Unable to compile TypeScript:
tests/mytest.test.ts:1:22 - error TS2307: Cannot find module './test-examples.yaml' or its corresponding type declarations.

1 import examples from './test-examples.yaml';

This works for Javascript but fails in Typescript

Is there a way to import Yaml into Typescript file via Webpack without errors?


Edit

Second try

  • Removing yaml-ts-loader`
  • Adding yaml-loader
  • Creating a global.d.ts
declare module '*.yaml' {
  const data: any;
  export default data;
}

  • Adding types to tsconfig.json
{
  "compilerOptions": {
    "outDir": "./dist",
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext", "es2015"],
    "sourceMap": true,
    "noEmitOnError": true,
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": false,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "module": "commonjs",
    "declaration": true,
    "downlevelIteration": true
  },
  "include": ["global.d.ts", "src"],
  "exclude": ["node_modules", "tests"]
}

Getting same result


Here is a snippet of the code that runs the tests.. (in package.json)

"scripts": {
    "test": "mocha -r ts-node/register tests/**/*.test.ts",
    ....
}

And the test imports yaml like so..

import examples from './test-examples.yaml';

But since I'm NOT using webpack for test (I don't think I am) could this be the problem? Is it necessary to compile my tests with Webpack (since it is the test file itself that is importing YAML), and then run the Mocha test on the compiled version? Or is that not necessary?

==============

Edit #2

I ended up side stepping the problem and using fs with a npm module that converts YAML to JSON.

3 Answers

Typescript doesn't know that you have webpack that lets you import yaml files, so it doesn't consider files that are not js or ts as modules. You need to explicitly tell typescript, what yaml modules are and what they export. This can be done by creating a types.d.ts file with this content:

declare module '*.yaml' {
  const data: any
  export default data
}

Then you need to let typescript know about this file by adding /// <reference path="/path/to/types.d.ts" /> line in files where you use it or by adding this file to include array in your tsconfig.

yaml-ts-loader is by the way supposed to generate .d.ts files for every yaml file, so if it actually does, you may also add those to include in tsconfig or /// <reference /> them

You should declare the module type somewhere in a "*.d.ts" file (just put it to the root if you have no one):

declare module '*.yaml' {
  const content: { [key: string]: any }
  export default content
}

I managed to make it work with

  ...
  module: {
    rules: [
      ...
      {
        test: /\.yaml$/,
        type: "json",
        use: "yaml-loader",
      },
    ]
  }
  ...

but now jest is choking on it

Related