Rollup-plugin-typescript2: Latest version doesn't resolve ts files included from js files

Created on 11 Sep 2019  ·  10Comments  ·  Source: ezolenko/rollup-plugin-typescript2

What happens and why it is wrong

The latest rpt2 (0.24.1) doesn't resolve ts files included from js files.

This works under rpt2 0.22.1 and earlier.

Versions

  • typescript: 3.6.2
  • rollup: 1.21.2
  • rollup-plugin-typescript2: 0.24.1

rollup.config.js

import typescript from "rollup-plugin-typescript2";
import commonjs from "rollup-plugin-commonjs";
import autoExternal from "rollup-plugin-auto-external";

const OUTPUT_DIR = process.env.OUTPUT_DIR || "build";

export default {
  input: ["src/processors/new-message-processor.js"]
  output: {
    dir: OUTPUT_DIR,
    format: "cjs"
  },
  external: ["nanoid/async"], // this one doesn't autoExtenal properly
  plugins: [
    autoExternal({
      builtins: true // handles nodeJS builtins
    }),
    commonjs(),
    typescript({
      typescript: require("typescript"),
      verbosity: 3
    })
  ]
};

tsconfig.json

{
  "compilerOptions": {
    "module": "ESNext",
    "allowJs": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "moduleResolution": "node",
    "noImplicitAny": true,
    "outDir": "./build",
    "target": "es2018",
    "baseUrl": "./src"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "build"]
}

plugin output with verbosity 3

Failing

src/processors/new-message-processor.js → build...
rpt2: built-in options overrides: {
    "noEmitHelpers": false,
    "importHelpers": true,
    "noResolve": false,
    "noEmit": false,
    "inlineSourceMap": false,
    "outDir": "/Users/kylejohnson/Demeter/backend/node_modules/.cache/rollup-plugin-typescript2/placeholder",
    "moduleResolution": 2,
    "allowNonTsExtensions": true
}
rpt2: parsed tsconfig: {
    "options": {
        "module": 99,
        "allowJs": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "moduleResolution": 2,
        "noImplicitAny": true,
        "outDir": "/Users/kylejohnson/Demeter/backend/node_modules/.cache/rollup-plugin-typescript2/placeholder",
        "target": 5,
        "baseUrl": "/Users/kylejohnson/Demeter/backend/src",
        "configFilePath": "/Users/kylejohnson/Demeter/backend/tsconfig.json",
        "noEmitHelpers": false,
        "importHelpers": true,
        "noResolve": false,
        "noEmit": false,
        "inlineSourceMap": false,
        "allowNonTsExtensions": true
    },
    "fileNames": [
// these don't differ between runs
    ],
    "typeAcquisition": {
        "enable": false,
        "include": [],
        "exclude": []
    },
    "raw": {
        "compilerOptions": {
            "module": "ESNext",
            "allowJs": true,
            "esModuleInterop": true,
            "allowSyntheticDefaultImports": true,
            "moduleResolution": "node",
            "noImplicitAny": true,
            "outDir": "./build",
            "target": "es2018",
            "baseUrl": "./src"
        },
        "include": [
            "src/**/*"
        ],
        "exclude": [
            "node_modules",
            "build"
        ],
        "compileOnSave": false
    },
    "errors": [],
    "wildcardDirectories": {
        "/users/kylejohnson/demeter/backend/src": 1
    },
    "compileOnSave": false,
    "configFileSpecs": {
        "includeSpecs": [
            "src/**/*"
        ],
        "excludeSpecs": [
            "node_modules",
            "build"
        ],
        "validatedIncludeSpecs": [
            "src/**/*"
        ],
        "validatedExcludeSpecs": [
            "node_modules",
            "build"
        ],
        "wildcardDirectories": {
            "/users/kylejohnson/demeter/backend/src": 1
        }
    }
}
rpt2: typescript version: 3.6.2
rpt2: tslib version: 1.10.0
rpt2: rollup version: 1.21.2
rpt2: rollup-plugin-typescript2 version: 0.24.1
rpt2: plugin options:
{
    "typescript": "version 3.6.2",
    "verbosity": 3,
    "check": true,
    "clean": false,
    "cacheRoot": "/Users/kylejohnson/Demeter/backend/node_modules/.cache/rollup-plugin-typescript2",
    "include": [
        "*.ts+(|x)",
        "**/*.ts+(|x)"
    ],
    "exclude": [
        "*.d.ts",
        "**/*.d.ts"
    ],
    "abortOnError": true,
    "rollupCommonJSResolveHack": false,
    "useTsconfigDeclarationDir": false,
    "tsconfigOverride": {},
    "transformers": [],
    "tsconfigDefaults": {},
    "objectHashIgnoreUnknownHack": false
}
rpt2: rollup config:
{
    "chunkGroupingSize": 5000,
    "experimentalCacheExpiry": 10,
    "external": [
// from node_modules, doesn't vary between runs
    ],
    "inlineDynamicImports": false,
    "input": [
        "src/processors/new-message-processor.js"
    ],
    "perf": false,
    "plugins": [
        {
            "name": "auto-external"
        },
        {
            "name": "commonjs"
        },
        {
            "name": "rpt2"
        }
    ],
    "strictDeprecations": false
}
rpt2: tsconfig path: /Users/kylejohnson/Demeter/backend/tsconfig.json
rpt2: included:
[
    "*.ts+(|x)",
    "**/*.ts+(|x)"
]
rpt2: excluded:
[
    "*.d.ts",
    "**/*.d.ts"
]
[!] Error: Could not resolve '../utils' from src/processors/new-message-processor.js
Error: Could not resolve '../utils' from src/processors/new-message-processor.js
    at error (/Users/kylejohnson/Demeter/backend/node_modules/rollup/dist/rollup.js:9558:30)
    at ModuleLoader.handleMissingImports (/Users/kylejohnson/Demeter/backend/node_modules/rollup/dist/rollup.js:16628:17)
    at ModuleLoader.<anonymous> (/Users/kylejohnson/Demeter/backend/node_modules/rollup/dist/rollup.js:16679:26)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/kylejohnson/Demeter/backend/node_modules/rollup/dist/rollup.js:40:28)

error Command failed with exit code 1.

Working

src/processors/new-message-processor.js → build...
rpt2: built-in options overrides: {
    "noEmitHelpers": false,
    "importHelpers": true,
    "noResolve": false,
    "noEmit": false,
    "inlineSourceMap": false,
    "outDir": "/Users/kylejohnson/Demeter/backend/.rpt2_cache/placeholder",
    "moduleResolution": 2,
    "allowNonTsExtensions": true
}
rpt2: parsed tsconfig: {
    "options": {
        "module": 99,
        "allowJs": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "moduleResolution": 2,
        "noImplicitAny": true,
        "outDir": "/Users/kylejohnson/Demeter/backend/.rpt2_cache/placeholder",
        "target": 5,
        "baseUrl": "/Users/kylejohnson/Demeter/backend/src",
        "configFilePath": "/Users/kylejohnson/Demeter/backend/tsconfig.json",
        "noEmitHelpers": false,
        "importHelpers": true,
        "noResolve": false,
        "noEmit": false,
        "inlineSourceMap": false,
        "allowNonTsExtensions": true
    },
    "fileNames": [
// same as above
    ],
    "typeAcquisition": {
        "enable": false,
        "include": [],
        "exclude": []
    },
    "raw": {
        "compilerOptions": {
            "module": "ESNext",
            "allowJs": true,
            "esModuleInterop": true,
            "allowSyntheticDefaultImports": true,
            "moduleResolution": "node",
            "noImplicitAny": true,
            "outDir": "./build",
            "target": "es2018",
            "baseUrl": "./src"
        },
        "include": [
            "src/**/*"
        ],
        "exclude": [
            "node_modules",
            "build"
        ],
        "compileOnSave": false
    },
    "errors": [],
    "wildcardDirectories": {
        "/users/kylejohnson/demeter/backend/src": 1
    },
    "compileOnSave": false,
    "configFileSpecs": {
        "includeSpecs": [
            "src/**/*"
        ],
        "excludeSpecs": [
            "node_modules",
            "build"
        ],
        "validatedIncludeSpecs": [
            "src/**/*"
        ],
        "validatedExcludeSpecs": [
            "node_modules",
            "build"
        ],
        "wildcardDirectories": {
            "/users/kylejohnson/demeter/backend/src": 1
        }
    }
}
rpt2: typescript version: 3.6.2
rpt2: tslib version: 1.10.0
rpt2: rollup version: 1.21.2
rpt2: rollup-plugin-typescript2 version: 0.22.1
rpt2: plugin options:
{
    "typescript": "version 3.6.2",
    "verbosity": 3,
    "check": true,
    "clean": false,
    "cacheRoot": "/Users/kylejohnson/Demeter/backend/.rpt2_cache",
    "include": [
        "*.ts+(|x)",
        "**/*.ts+(|x)"
    ],
    "exclude": [
        "*.d.ts",
        "**/*.d.ts"
    ],
    "abortOnError": true,
    "rollupCommonJSResolveHack": false,
    "useTsconfigDeclarationDir": false,
    "tsconfigOverride": {},
    "transformers": [],
    "tsconfigDefaults": {},
    "objectHashIgnoreUnknownHack": false
}
rpt2: rollup config:
{
    "chunkGroupingSize": 5000,
    "experimentalCacheExpiry": 10,
    "external": [
// same as above
    ],
    "inlineDynamicImports": false,
    "input": [
        "src/processors/new-message-processor.js"
    ],
    "perf": false,
    "plugins": [
        {
            "name": "auto-external"
        },
        {
            "name": "commonjs"
        },
        {
            "name": "rpt2"
        }
    ],
    "strictDeprecations": false
}
rpt2: tsconfig path: /Users/kylejohnson/Demeter/backend/tsconfig.json
rpt2: included:
[
    "*.ts+(|x)",
    "**/*.ts+(|x)"
]
rpt2: excluded:
[
    "*.d.ts",
    "**/*.d.ts"
]
rpt2: Ambient types:
rpt2:     /Users/kylejohnson/Demeter/backend/src/global.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/accepts/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/babel__core/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/babel__generator/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/babel__template/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/babel__traverse/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/bl/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/body-parser/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/caseless/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/connect/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/cookies/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/eslint-visitor-keys/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/estree/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/events/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/express/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/express-serve-static-core/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/form-data/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/formidable/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/http-assert/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/istanbul-lib-coverage/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/istanbul-lib-report/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/istanbul-reports/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/jest/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/jest-diff/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/json-schema/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/json5/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/jsonwebtoken/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/keygrip/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/koa/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/koa-compose/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/koa-router/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/long/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/mime/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/node/ts3.2/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/pg/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/pg-types/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/pino/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/pino-std-serializers/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/range-parser/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/request/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/resolve/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/serve-static/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/sonic-boom/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/stack-utils/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/stream-to-array/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/tough-cookie/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/yargs/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/yargs-parser/index.d.ts
rpt2:     /Users/kylejohnson/Demeter/backend/node_modules/@types/yauzl/index.d.ts
rpt2: ambient types changed, redoing all semantic diagnostics
rpt2: dependency '/Users/kylejohnson/Demeter/backend/src/utils.ts'
rpt2:     imported by '/Users/kylejohnson/Demeter/backend/src/processors/new-message-processor.js'
rpt2: resolving '../utils' imported by '/Users/kylejohnson/Demeter/backend/src/processors/new-message-processor.js'
rpt2:     to '/Users/kylejohnson/Demeter/backend/src/utils.ts'
rpt2: dependency '/Users/kylejohnson/Demeter/backend/src/processors/message-handler-framework.ts'
rpt2:     imported by '/Users/kylejohnson/Demeter/backend/src/processors/new-message-processor.js'
rpt2: resolving './message-handler-framework' imported by '/Users/kylejohnson/Demeter/backend/src/processors/new-message-processor.js'
rpt2:     to '/Users/kylejohnson/Demeter/backend/src/processors/message-handler-framework.ts'
rpt2: dependency '/Users/kylejohnson/Demeter/backend/src/buffered-channel.ts'
rpt2:     imported by '/Users/kylejohnson/Demeter/backend/src/processors/new-message-processor.js'
rpt2: resolving '../buffered-channel' imported by '/Users/kylejohnson/Demeter/backend/src/processors/new-message-processor.js'
rpt2:     to '/Users/kylejohnson/Demeter/backend/src/buffered-channel.ts'
rpt2: transpiling '/Users/kylejohnson/Demeter/backend/src/utils.ts'
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/code/cache/6895f7e81850383bec8a4facc7e6e179d2c36c2a'
rpt2:     cache miss
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/syntacticDiagnostics/cache/6895f7e81850383bec8a4facc7e6e179d2c36c2a'
rpt2:     cache miss
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/semanticDiagnostics/cache/6895f7e81850383bec8a4facc7e6e179d2c36c2a'
rpt2:     cache miss
rpt2: transpiling '/Users/kylejohnson/Demeter/backend/src/processors/message-handler-framework.ts'
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/code/cache/bd72d31b4317d7b2d9cd3f1d29bc790c76468d5a'
rpt2:     cache miss
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/syntacticDiagnostics/cache/bd72d31b4317d7b2d9cd3f1d29bc790c76468d5a'
rpt2:     cache miss
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/semanticDiagnostics/cache/bd72d31b4317d7b2d9cd3f1d29bc790c76468d5a'
rpt2:     cache miss
rpt2: dependency '/Users/kylejohnson/Demeter/backend/src/aws.ts'
rpt2:     imported by '/Users/kylejohnson/Demeter/backend/src/processors/message-handler-framework.ts'
rpt2: resolving '../aws' imported by '/Users/kylejohnson/Demeter/backend/src/processors/message-handler-framework.ts'
rpt2:     to '/Users/kylejohnson/Demeter/backend/src/aws.ts'
rpt2: transpiling '/Users/kylejohnson/Demeter/backend/src/buffered-channel.ts'
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/code/cache/6a7cbb15c399dd3ba3546f1ccc0686609add6344'
rpt2:     cache miss
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/syntacticDiagnostics/cache/6a7cbb15c399dd3ba3546f1ccc0686609add6344'
rpt2:     cache miss
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/semanticDiagnostics/cache/6a7cbb15c399dd3ba3546f1ccc0686609add6344'
rpt2:     cache miss
rpt2: dependency '/Users/kylejohnson/Demeter/backend/src/aws.ts'
rpt2:     imported by '/Users/kylejohnson/Demeter/backend/src/buffered-channel.ts'
rpt2: resolving './aws' imported by '/Users/kylejohnson/Demeter/backend/src/buffered-channel.ts'
rpt2:     to '/Users/kylejohnson/Demeter/backend/src/aws.ts'
rpt2: transpiling '/Users/kylejohnson/Demeter/backend/src/aws.ts'
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/code/cache/cc5447b8d6c1f999fb4bf4c04b2704ed191d0f41'
rpt2:     cache miss
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/syntacticDiagnostics/cache/cc5447b8d6c1f999fb4bf4c04b2704ed191d0f41'
rpt2:     cache miss
rpt2:     cache: '/Users/kylejohnson/Demeter/backend/.rpt2_cache/rpt2_7949c609ec7b2114d4476feb47433d93ccf7c5ed/semanticDiagnostics/cache/cc5447b8d6c1f999fb4bf4c04b2704ed191d0f41'
rpt2:     cache miss
rpt2: generating target 1
rpt2: rolling caches
created build in 18.3s
✨  Done in 19.30s.
bug

All 10 comments

I am having the same issue. Surprisingly it seems to work when importing ./myfile.ts instead of ./myfile but VScode shows an error An import path cannot end with a '.ts' extension. Consider importing './myfile' instead.

non-relative paths also seem to be broken (using baseUrl option in tsconfig.json)

In 0.22.1:

When importing a typescript module from a .js file
import m1 from "./module1" => works
import m1 from "./module1.ts" => works
import m2 from "lib/module2" => works
import m2 from "lib/module2.ts" => does not work
import m2 from "./lib/module2.ts" => works

In 0.23.0+:

When importing a typescript module from a .js file
import m1 from "./module1" => does not work anymore
import m1 from "./module1.ts" => works
import m2 from "lib/module2" => does not work anymore
import m2 from "lib/module2.ts" => does not work
import m2 from "./lib/module2.ts" => works

@kyle-johnson could you actually post the file list? Since 0.23.0 plugin avoids resolving imports from files that are not found by typescript based on tsconfig settings. I'm curious if src/processors/new-message-processor.js is in the list (looks like it should be, since you have allowJs: true)

    "fileNames": [
// these don't differ between runs
    ],

Yes, it's in there:

    "fileNames": [
[...]
        "/Users/kylejohnson/Demeter/backend/src/utils.ts",
[...]
        "/Users/kylejohnson/Demeter/backend/src/processors/new-message-processor.js",
[...]
    ],

Could you add include: ["*.ts+(|x)", "**/*.ts+(|x)", "*.js"] to plugin options and try it? If it works I'll add js extensions if allowJs is set in tsconfig.

@kyle-johnson could you try 0.24.3? might be fixed now.

0.24.3 doesn't fix the issue for me. I have a simple project that last worked on 0.22.1

git clone https://github.com/nickbabcock/vigenere.git
cd vigenere
git checkout dependabot/npm_and_yarn/rollup-plugin-typescript2-0.24.3
npm ci
npm run build

Results in the following error:

src/main.js → public/bundle.js...
[!] Error: Could not resolve './core/vigenere-cipher' from src/App.svelte
Error: Could not resolve './core/vigenere-cipher' from src/App.svelte
    at error (/tmp/vigenere/node_modules/rollup/dist/rollup.js:9558:30)
    at ModuleLoader.handleMissingImports (/tmp/vigenere/node_modules/rollup/dist/rollup.js:16628:17)
    at ModuleLoader.<anonymous> (/tmp/vigenere/node_modules/rollup/dist/rollup.js:16679:26)
    at Generator.next (<anonymous>)
    at fulfilled (/tmp/vigenere/node_modules/rollup/dist/rollup.js:40:28)

0.24.3 fixes it for my case

@nickbabcock your stuff seem to compile if I change import to ./core/vigenere-cipher.ts. Can't tell if the bundle is correct or not.

Looks like rpt2 doesn't resolve the import itself because source file is not even js and whatever ends up resolving import for rollup doesn't recognize ts files.

Thanks for the insight, my svelte and rollup knowledge is fledgling -- the bundle turned out correct. 🎉

Was this page helpful?
0 / 5 - 0 ratings