Converts require
statements to ES6-style import
.
Apply with the Grit CLI
grit apply es6_imports
Transform standard require statements
BEFORE
const defaultImport = require('../../shared/default').default; const { something, another } = require('./lib'); const { value, original: renamed } = require('something'); const otherName = require('chai').ogName; const assert = require('chai').assert; const conf = require('chai').config; const starImport = require('star');
AFTER
import defaultImport from '../../shared/default'; import { something, another } from './lib'; import { value, original as renamed } from 'something'; import { ogName as otherName } from 'chai'; import { assert } from 'chai'; import { config as conf } from 'chai'; import starImport from 'star';
Handle dotenv
BEFORE
require('dotenv').config({ path: '../.env' }); // Another example require('dotenv').config(); function doStuff() { // hello world }
AFTER
import * as dotenv from 'dotenv'; dotenv.config({ path: '../.env' }); // Another example import * as dotenv from 'dotenv'; dotenv.config(); function doStuff() { // hello world }
Handle Sentry
BEFORE
const Sentry = require('@sentry/node');
This appears to be correct based on open source examples.
AFTER
import * as Sentry from '@sentry/node';
Handle deep props
BEFORE
const assert = require('test-lib').assert, path = require('path'), hash = require('../hash'), { Some: { Deep: { Concerns }, }, } = require('@org/pkg'), { ancestorExport } = require('../../ancestor'); const defaultOptions = require('../../conf/default-cli-options'); const pkg = require('../../package.json'); const { Legacy: { ConfigOps, naming, CascadingConfigArrayFactory, IgnorePattern, getUsedExtractedConfigs, ModuleResolver, }, } = require('@org/pkg'); const proxyquire = require('proxyquire').noCallThru().noPreserveCache();
AFTER
import { assert } from 'test-lib'; import path from 'path'; import hash from '../hash'; import { Some } from '@org/pkg'; const { Deep: { Concerns }, } = Some; import { ancestorExport } from '../../ancestor'; import defaultOptions from '../../conf/default-cli-options'; import pkg from '../../package.json'; import { Legacy } from '@org/pkg'; const { ConfigOps, naming, CascadingConfigArrayFactory, IgnorePattern, getUsedExtractedConfigs, ModuleResolver, } = Legacy; import __proxyquire from 'proxyquire'; const proxyquire = __proxyquire.noCallThru().noPreserveCache();
Dynamic imports
Require statements that are not at the root of the program are converted to dynamic imports, using await import()
.
BEFORE
const { something } = require('./lib'); async function doStuff() { const { another } = require('another'); // Handle sentry correctly too const Sentry = require('@sentry/node'); // Destructure const { somethingElse: { finalThing }, } = require('another'); }
AFTER
import { something } from './lib'; async function doStuff() { const { another } = await import('another'); // Handle sentry correctly too const Sentry = await import('@sentry/node'); // Destructure const { somethingElse: { finalThing }, } = await import('another'); }
Inline require usage
Require statements that are used without being assigned to a variable are ignored.
JS
const input = await fs.readFile(require('path').resolve(__dirname, 'test.txt'), 'utf8');
Function usage
Requires inside a code block should also be ignored.
JS
const command = initUtil({ async run() { var proc = require('child_process').spawn('ls', ['-l']); }, });
Ignore dynamically generated requires
Template literals and other computed requires cannot use import.
JS
const mybrand = 'grit'; const { something } = require(`./${mybrand}/lib`);