10
votes

We are starting to mix in some es6 modules and eslint justly complains when you use import/export when not using the sourceType: script

Parsing error: 'import' and 'export' may appear only with 'sourceType: module'at line 1 col 1

However if I change sourceType to module then every file that has 'use strict'; at the top gets flagged saying use strict isn't needed in modules.

The modules are my jsx files and my js files are POJ so I need both sourceTypes to be operating.

Any ideas on how to coerce eslint to behave with both modules and scripts? I would like to avoid running two seperate eslintrc files and rule sets just to have one be modules and the other be scripts.

4
Why don't you disable the rule that flags use strict as not needed? (I assume that's possible)Felix Kling

4 Answers

13
votes

As long as as your scripts have one extension and your modules have a different extension, then you can have two different configs.

// .eslintrc.json
{
    // ...
    // Your normal config goes here
    // ...
}

Lint your normal scripts with eslint ., just like you've been doing. It defaults to sourceType: "script", pulls .eslintrc.json by default, and only lints *.js files by default.

// .eslintrc.modules.json
{
    "extends": "./.eslintrc.json",
    "parserOptions": {
        "sourceType": "module"
    },
    // You can have additional module-specific config here if you want
}

Now you can lint just the modules using eslint --config .eslintrc.modules.json --ext .jsx ., which will pull the modules config, which is just an extension of the normal .eslintrc.json, and it will only lint the *.jsx files.

2
votes

I've created the main file in the root folder with option sourceType: script. When in a folder ./front file .eslintrc.json:

{
    "extends": "../.eslintrc.json",
    "parserOptions": {
        "sourceType": "module"
    }
}
1
votes

There's a nicer approach now in eslint 4.1.0+:

module.exports = {
  overrides: [
    {
      files: [ "rollup.config.js" ],
      parserOptions: { sourceType: "module" },
    }
  ]
};

You can also change rules or whatever you want, per-glob, in the overrides section.

0
votes

There is a way to have your cake and eat it too, keeping all your files with the .js extension while disambiguating the sourceTypes of files.

First, like the other answers suggest, add an override for an alternate file extension:

 { "overrides":
            [
            { "files": [ "*.js" ]
            , "excludedFiles": "*unambiguous.js"
            , "processor": "plugin-name/disambiguate" }
            ,
            { "files": [ "*.mjs" ]
            , "parserOptions":
                    { "sourceType": "module" } }
            ] }

Then comes the magic: make a super simple ESLint plugin like so

var module_regex = /\bimport\b|\bexport\b/

module .exports =
        { processors:
                { disambiguate:
                        { preprocess: (_source_string, _file_path) => {
                                if (module_regex .test (_source_string)) {
                                        return [
                                                { text:  _source_string
                                                , filename: 'unambiguous.mjs' } ] }
                                else {
                                        return [
                                                { text: _source_string
                                                , filename: 'unambiguous.js' } ] } } } } }

With this setup, after the ESLint plugin disambiguates your Javascript code, ESLint understands your sourceType just as its supposed to, with no changes to .js file extensions needed.

This fits well with the ESLint configuration/plugin model, and as a plugin you can even put the "overrides" in the plugin config so that all your base config needs is to do is to include the plugin, to make the disambiguation work.

May consider putting this up on npm sometime, hope this helps someone.