Skip to content

Commit

Permalink
fix: import("eslint") doesn't work (#9)
Browse files Browse the repository at this point in the history
* fix: import("eslint") doesn't work

fixes #8

* fix: failing tests

* fix: safer import

* Update lib/init/config-file.js

Co-authored-by: Nicholas C. Zakas <[email protected]>

Co-authored-by: Nicholas C. Zakas <[email protected]>
  • Loading branch information
aladdin-add and nzakas authored Dec 18, 2021
1 parent 1026c16 commit 48d8025
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 100 deletions.
90 changes: 2 additions & 88 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,101 +6,15 @@ yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

.vscode
.vscode
/tmp
20 changes: 18 additions & 2 deletions lib/init/config-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ import fs from "fs";
import path from "path";
import stringify from "json-stable-stringify-without-jsonify";
import debugEsm from "debug";
import { pathToFileURL } from "url";
import { createRequire } from "module";

const debug = debugEsm("eslint:config-file");
const require = createRequire(path.join(process.cwd(), "./__placeholder__"));

//------------------------------------------------------------------------------
// Helpers
Expand All @@ -31,6 +34,17 @@ function sortByKey(a, b) {
return a.key > b.key ? 1 : -1;
}

/**
* import local-installed package
* @param {string} pkgName the package name to import
* @returns {Promise<*>} the exported module
*/
async function importLocalPackage(pkgName) {
const pkgPath = require.resolve(pkgName);

return await import(pathToFileURL(pkgPath)); // eslint-disable-line node/no-unsupported-features/es-syntax
}

//------------------------------------------------------------------------------
// Private
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -84,8 +98,10 @@ async function writeJSConfigFile(config, filePath) {
const stringifiedContent = `module.exports = ${stringify(config, { cmp: sortByKey, space: 4 })}\n`;

try {
// eslint-disable-next-line node/no-unsupported-features/es-syntax
const eslint = (await import("eslint"));

// import("eslint") won't work when running npx.
// as `@eslint/create-config` was installed in npm-cache, while eslint was installed in cwd.
const eslint = (await importLocalPackage("eslint")).default;
const linter = new eslint.ESLint({ baseConfig: config, fix: true, useEslintrc: false });
const result = await linter.lintText(stringifiedContent);

Expand Down
3 changes: 0 additions & 3 deletions tests/fixtures/eslint/index.js

This file was deleted.

12 changes: 12 additions & 0 deletions tests/fixtures/eslint/lib/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* @fileoverview the file is to mock local-installed eslint for testing
*/
"use strict";
const _module = require("module");
const path = require("path");

const { createRequire } = _module;
const root = path.resolve(__dirname, "../../../../../../");

const realEslintPath = createRequire(root).resolve("eslint");
module.exports = require(realEslintPath);
3 changes: 2 additions & 1 deletion tests/fixtures/eslint/package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"name": "eslint",
"version": "3.18.0"
"version": "3.18.0",
"main": "./lib/api.js"
}
2 changes: 1 addition & 1 deletion tests/init/config-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ describe("ConfigFile", () => {

const StubbedConfigFile = await esmock.p("../../lib/init/config-file.js", {
fs: fakeFS,
eslint: { ESLint: fakeESLint }
eslint: { default: { ESLint: fakeESLint } }
});

nodeAssert.rejects(async () => {
Expand Down
17 changes: 12 additions & 5 deletions tests/init/config-initializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@
import chai from "chai";
import fs from "fs";
import path from "path";
import os from "os";
import sinon from "sinon";
import sh from "shelljs";
import * as npmUtils from "../../lib/init/npm-utils.js";
import esmock from "esmock";
import { fileURLToPath } from "url";
import * as npmUtils from "../../lib/init/npm-utils.js";

const originalDir = process.cwd();
const { assert } = chai;


//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
Expand All @@ -35,7 +34,13 @@ let localInstalledEslintDir;
*/
function setLocalInstalledEslint(version) {
const eslintPkgPath = path.join(localInstalledEslintDir, "./package.json");
const pkg = version ? { name: "eslint", version } : {};
let pkg = JSON.parse(fs.readFileSync(eslintPkgPath, "utf8"));

if (version) {
pkg.version = version;
} else {
pkg = {};
}

fs.writeFileSync(eslintPkgPath, JSON.stringify(pkg, null, 2), "utf8");
}
Expand All @@ -60,7 +65,9 @@ describe("configInitializer", () => {

// copy into clean area so as not to get "infected" by this project's .eslintrc files
before(() => {
fixtureDir = path.join(os.tmpdir(), "eslint/fixtures/config-initializer");
const __filename = fileURLToPath(import.meta.url); // eslint-disable-line no-underscore-dangle

fixtureDir = path.join(__filename, "../../../tmp/eslint/fixtures/config-initializer");
localInstalledEslintDir = path.join(fixtureDir, "./node_modules/eslint");
sh.mkdir("-p", localInstalledEslintDir);
sh.cp("-r", "./tests/fixtures/config-initializer/.", fixtureDir);
Expand Down

0 comments on commit 48d8025

Please sign in to comment.