@putout/plugin-esm
v9.11.1
Published
πPutout plugin improves ability to transform ESM code
Maintainers
Readme
@putout/plugin-esm 
The static
importstatement is used toimportread only live bindings which are exported by another module. The imported bindings are called live bindings because they are updated by the module that exported the binding, but cannot be re-assigned by the importing module.(c) MDN
πPutout plugin adds ability to transform to new Node.js API and apply best practices.
Install
npm i putout @putout/plugin-esm -DRules
- β apply-default-import;
- β apply-export-from;
- β apply-import-import;
- β convert-assert-to-with;
- β declare-imports-first;
- β group-imports-by-source;
- β merge-duplicate-imports;
- β merge-declaration-with-export;
- β merge-export-declarations;
- β remove-quotes-from-import-assertions;
- β remove-empty-import;
- β remove-empty-export;
- β remove-useless-export-specifiers;
- β sort-imports-by-specifiers;
File rules
- β apply-name-to-imported-file;
- β apply-namespace-to-imported-file;
- β apply-privately-imported-file;
- β apply-js-imported-file;
- β resolve-imported-file;
- β shorten-imported-file;
Config
{
"rules": {
"esm/apply-default-import": "on",
"esm/apply-export-from": "on",
"esm/apply-import-attirbutes": "on",
"esm/declare-imports-first": "on",
"esm/group-imports-by-source": "on",
"esm/merge-duplicate-imports": "on",
"esm/merge-declaration-with-export": "on",
"esm/merge-export-declaration": "on",
"esm/remove-quotes-from-import-assertions": "on",
"esm/remove-empty-export": "on",
"esm/remove-empty-import": ["on", {
"ignore": []
}],
"esm/sort-imports-by-specifiers": "on",
"esm/apply-js-imported-file": "off",
"esm/resolve-imported-file": "off",
"esm/shorten-imported-file": "off",
"esm/apply-name-to-imported-file": "off",
"esm/apply-namespace-to-imported-file": "off",
"esm/apply-privately-imported-file": "off",
"esm/remove-useless-export-specifiers": "off"
}
}Rules
apply-default-import
The static
importdeclaration is used to import read-only live bindings which are exported by another module.(c) MDN
Check out πPutout Editor.
β Example of incorrect code
import {default as a} from 'a';β Example of correct code
import a from 'a';apply-export-from
The
exportdeclaration is used to export values from a JavaScript module.(c) MDN
Check out πPutout Editor:
β Example of incorrect code
import * as ns_1 from 'x';
import {createAsyncLoader} from './load/async-loader.js';
export {
ns_1 as ns,
createAsyncLoader,
};β Example of correct code
export * as ns from 'x';
export {createAsyncLoader} from './load/async-loader.js';apply-import-attributes
The import attributes feature instructs the runtime about how a module should be loaded, including the behavior of module resolution, fetching, parsing, and evaluation.
(c) MDN
Check out πPutout Editor.
β Example of incorrect code
import a from '../package.json';
export * as x from './package.json';
await import('./package.json');β Example of correct code
import a from '../package.json' with {
type: 'json',
};
export * from './package.json' with {
type: 'json',
};
await import('./package.json', {
with: {
type: 'json',
},
});merge-declaration-with-export
Checkout in πPutout Editor.
β Example of incorrect code
const stack = [];
function sum(a, b) {
i32.add(local.get(), local.get());
}
export {
sum,
stack,
};β Example of correct code
export const stack = [];
export function sum(a, b) {
i32.add(local.get(), local.get());
}
export const {
report,
fix,
scan,
} = createRemoveFiles(['*.swp', '*.swo']);merge-export-declarations
Checkout in πPutout Editor.
β Example of incorrect code
export {
loadPlugins,
};
export {
loadPluginsAsync,
};β Example of incorrect code
export {
loadPlugins,
loadPluginsAsync,
};remove-useless-export-specifiers
Check out in πPutout Editor.
β Example of incorrect code
export const hello = () => 'world';
export const {
- hello,
}declare-imports-first
Check out in πPutout Editor. For CommonJS use nodejs/declare-after-require.
β Example of incorrect code
const [arg] = process.argv;
import esbuild from 'esbuild';β Example of correct code
import esbuild from 'esbuild';
const [arg] = process.argv;group-imports-by-source
Group order:
- β builtins;
- β external;
- β hashed;
- β internal;
Checkout in πPutout Editor.
β Example of incorrect code
import fs from 'node:fs';
import {lodash} from 'lodash';
import react from 'react';
import d from '../hello.js';
import ss from '../../bb/ss.js';
import b from './ss.js';
import parse from '#parser';
const c = 5;β Example of correct code
import fs from 'node:fs';
import react from 'react';
import {lodash} from 'lodash';
import parse from '#parser';
import b from './ss.js';
import d from '../hello.js';
import ss from '../../bb/ss.js';
const c = 5;merge-duplicate-imports/join
β Example of incorrect code
import test from 'supertape';
import {stub} from 'supertape';β Example of correct code
import test, {stub} from 'supertape';merge-duplicate-imports/rename
Checkout in πPutout Editor. To disable use:
{
"rules": {
"esm/merge-duplicate-imports-rename": "off"
}
}β Example of incorrect code
import putout from './putout.js';
import all from './putout.js';
import x from './putout.js';
console.log(all);
console.log(x);β Example of correct code
import putout from './putout.js';
console.log(putout);
console.log(putout);remove-empty-export
-export {};remove-empty-import
-import 'abc';remove-quotes-from-import-assertions
Checkout in πPutout Editor.
β Example of incorrect code
import json from './mod.json' with {
type: 'json',
};β Example of correct code
import json from './mod.json' with {
type: 'json',
};sort-imports-by-specifiers
Checkout in πPutout Editor.
β Example of incorrect code
import {
a,
b,
c,
d,
} from 'd';
import a1 from 'a1';β Example of correct code
import a1 from 'a1';
import {
a,
b,
c,
d,
} from 'd';convert-assert-to-with
This feature would ideally use the
withkeyword to denote attributes, but there are existing implementations based on a previous version of the proposal using theassertkeyword. Due to potential web compatibility risks, the proposal still includesassertmarked as deprecated. Usage of the old syntax is discouraged, and its removal is being investigated.(c) tc39
Check out in πPutout Editor.
β Example of incorrect code
import json from './foo.json' assert {
type: 'json',
};
import('foo.json', {
assert: {
type: 'json',
},
});β Example of correct code
import json from './foo.json' with {
type: 'json',
};
import('foo.json', {
with: {
type: 'json',
},
});File Rules
apply-namespace-to-imported-file
The rule fixes:
SyntaxError: The requested module './a.js' does not provide an export named 'default'
Check out in πPutout Editor:
- β
apply-namespace-to-imported-file; - β
get-imports; - β
has-export-default; - β
apply-namespace-import; - β
is-esm;
Let's consider file structure:
/
βββ lib/
βββ index.js "import a from './a.js';"
βββ b.js "export const b = 2;" In this case index.js can be fixed:
β Example of incorrect code
import a from './a.js';β Example of correct code
import * as a from './a.js';apply-name-to-imported-file
Checkout in πPutout Editor:
- β
get-imports; - β
has-export-default; - β
is-esm;
Let's consider file structure:
/
βββ lib/
βββ index.js "import a from './a.js';\n export * as b from './b.js'"
βββ a.js "export const a = 2;"
βββ b.js "export const b = 2;" In this case index.js can be fixed:
β Example of incorrect code
import a from './a.js';
export * as b from './b.js';β Example of correct code
import {a} from './a.js';
export {b} from './b.js';apply-privately-imported-file
Entries in the imports field must be strings starting with
#. Package imports permit mapping to external packages. This field defines subpath imports for the current package.(c) nodejs.org
Check out in πPutout Editor:
- β
get-imports; - β
change-imports;
Let's consider file structure:
/
βββ package.json {"imports": {"#is: {"default": "./lib/tokenize/is.js"}}}
βββ lib/
βββ tokenize/
βββ is.js "export const isPrev = () => {}"
βββ expressions/
βββ spread-element.js "import {isPrev} from '../is.js"In this case spread-element.js can be fixed:
β Example of incorrect code
import {isPrev} from '../is.js';β Example of correct code
import {isPrev} from '#is';resolve-imported-file
importa directory URL is unsupported.(c) nodejs.org
Check out in πPutout Editor:
- β
resolve-imported-file; - β
get-imports; - β
change-imports;
Let's consider file structure:
/
βββ package.json
βββ lib/
βββ index.js
βββ a.jsIn this case index.js can be fixed:
β Example of incorrect code
import a from './a';
import info from '../package';β Example of correct code
import a from './a.js';
import info from '../package.json' with {
type: 'json',
};shorten-imported-file
Check out in πPutout Editor:
- β
get-imports; - β
change-imports;
Let's consider file structure:
/
βββ processors/
βββ index.js
βββ parse-processor-names.jsIn this case index.js can be fixed:
β Example of incorrect code
import {parseProcessorNames} from '../processors/parse-processor-names.js';β Example of correct code
import {parseProcessorNames} from './parse-processor-names.js';apply-js-imported-file
Checkout in πPutout Editor:
- β
get-imports; - β
change-imports;
Let's consider file structure:
/
βββ lib/
βββ index.js
βββ a.jsIn this case index.js can be fixed:
β Example of incorrect code
import a from './a.mjs';β Example of correct code
import a from './a.js';License
MIT
