Skip to content

Commit

Permalink
Merge pull request #517 from philolo1/root-fix
Browse files Browse the repository at this point in the history
Ignore packages containing "importjs": { "isRoot": false }
  • Loading branch information
trotzig authored Sep 12, 2018
2 parents ced2344 + b9e202a commit 40aad13
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 7 deletions.
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ contribute](CONTRIBUTING.md).

## Dependency on Babel 7

ImportJS uses [Babel 7](https://babeljs.io/docs/en/next/v7-migration.html) from version [3.1.0](https://github.com/Galooshi/import-js/releases/tag/v3.1.0). In most cases, Babel 7 is backwards-compatible with Babel 6, but if you run into issues (such as [this one about decorators](https://github.com/Galooshi/import-js/issues/515)), consider installing a previous version of ImportJS (e.g. [3.0.0](https://github.com/Galooshi/import-js/releases/tag/v3.0.0)) or updating your project to be Babel 7 compatible.
ImportJS uses [Babel 7](https://babeljs.io/docs/en/next/v7-migration.html) from version [3.1.0](https://github.com/Galooshi/import-js/releases/tag/v3.1.0). In most cases, Babel 7 is backwards-compatible with Babel 6, but if you run into issues (such as [this one about decorators](https://github.com/Galooshi/import-js/issues/515)), consider installing a previous version of ImportJS (e.g. [3.0.0](https://github.com/Galooshi/import-js/releases/tag/v3.0.0)) or updating your project to be Babel 7 compatible.


## Importing: Example
Expand Down Expand Up @@ -649,6 +649,38 @@ Since the `--overwrite` flag makes ImportJS destructive (files are overwritten),
it's a good thing to double-check that the `find` command returns the right
files before adding the `-exec` part.

## Specifying alternate package directory

ImportJS looks for the `package.json` file in the closest ancestor directory for the file you're editing to find node modules to import. However, sometimes it might pull dependencies from a directory further up the chain. For example, your directory structure might look like this:

```
.
|-- package.json
|-- components
| |-- button.js
| |-- icon.js
|-- node_modules
| |-- react
|-- subpackage
| |-- package.json
| |-- components
| |-- bulletin.js
```

If you were to use ImportJS on `subpackage/components/bulletin.js` which imports React, ImportJS would not know that `react` is a valid dependency.

To tell ImportJS to skip a directory and keep searching upwards to find the root package directory, specify `"importjs": { "isRoot": false }` in the `package.json` of the directory to ignore. In this case, you would want something like this:

```json
{
"name": "subpackage",
...
"importjs": {
"isRoot": false
}
}
```

## Running as a daemon

*Note*: This section is intended mostly for developers of editor plugins. If
Expand Down
31 changes: 26 additions & 5 deletions lib/__tests__/findProjectRoot-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,24 @@ jest.mock('fs');

afterEach(() => fs.__reset());

const normalPackageJsonContents = `{
"name": "some-package",
"dependencies": {
}
}`;

it('finds the right folders', () => {
// FileUtils.__setFile(path.join(process.cwd(), '.importjs.js'), {
fs.__setFile(path.join(path.resolve('/'), 'foo', 'package.json'));
fs.__setFile(path.join(path.resolve('/'), 'foo', 'bar', 'package.json'));
fs.__setFile(path.join(path.resolve('/'), 'foo', 'package.json'), normalPackageJsonContents);
fs.__setFile(path.join(path.resolve('/'), 'foo', 'bar', 'package.json'), normalPackageJsonContents);
expect(findProjectRoot(path.join(path.resolve('/'), 'foo', 'bar', 'baz.js')))
.toEqual(path.join(path.resolve('/'), 'foo', 'bar'));
});

it('treats package folders as roots', () => {
fs.__setFile(path.join(path.resolve('/'), 'foo', 'package.json'));
fs.__setFile(path.join(path.resolve('/'), 'foo', 'node_modules', 'bar', 'package.json'));
fs.__setFile(path.join(path.resolve('/'), 'foo', 'package.json'), normalPackageJsonContents);
fs.__setFile(path.join(path.resolve('/'), 'foo', 'node_modules', 'bar', 'package.json'), normalPackageJsonContents);
// expect(findProjectRoot('/foo/node_modules/bar/baz/gaz.js')).toEqual(
expect(findProjectRoot(path.join(path.resolve('/'), 'foo', 'node_modules', 'bar', 'baz', 'gaz.js')))
.toEqual(path.join(path.resolve('/'), 'foo', 'node_modules', 'bar'));
Expand All @@ -28,7 +35,21 @@ it('throws if it can not find a folder', () => {
});

it('works for relative paths as well', () => {
fs.__setFile(path.join(process.cwd(), path.join('foo', 'package.json')));
fs.__setFile(path.join(process.cwd(), path.join('foo', 'package.json')), normalPackageJsonContents);
expect(findProjectRoot(path.join('foo', 'bar', 'baz.js'))).toEqual(path.join(process.cwd(), 'foo'));
expect(findProjectRoot(path.join('.', 'foo', 'bar', 'baz.js'))).toEqual(path.join(process.cwd(), 'foo'));
});

it('ignores directories in which the package.json specifies "importjs": { "isRoot": false }', () => {
fs.__setFile(path.join(path.resolve('/'), 'foo', 'package.json'), normalPackageJsonContents);
fs.__setFile(path.join(path.resolve('/'), 'foo', 'bar', 'package.json'), `{
"name": "not-root",
"dependencies": {
},
"importjs": {
"isRoot": false
}
}`);
expect(findProjectRoot(path.join('/', 'foo', 'bar', 'baz.js'))).toEqual(path.join(path.resolve('/'), 'foo'));
});
18 changes: 17 additions & 1 deletion lib/findProjectRoot.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
import fs from 'fs';
import path from 'path';

import FileUtils from './FileUtils';

const isWinDriveRoot = /^[A-Z]:\\$/;

function isRootPackageJson(path) {
if (!fs.existsSync(path)) {
return false;
}

const packageJson = FileUtils.readJsonFile(path);

if ('importjs' in packageJson && 'isRoot' in packageJson.importjs) {
return packageJson.importjs.isRoot;
}

return true;
}

function findRecursive(directory) {
if (directory === '/' || isWinDriveRoot.test(directory)) {
throw new Error('No project root found, looking for a directory with a package.json file.');
}

const pathToPackageJson = path.join(directory, 'package.json');

if (fs.existsSync(pathToPackageJson)) {
if (isRootPackageJson(pathToPackageJson)) {
return directory;
}

Expand Down

0 comments on commit 40aad13

Please sign in to comment.