Skip to content

Commit

Permalink
Update: add allowModules option.
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea committed May 5, 2016
1 parent 741e900 commit 23f6fba
Show file tree
Hide file tree
Showing 15 changed files with 219 additions and 6 deletions.
29 changes: 27 additions & 2 deletions docs/rules/no-missing-import.md
Expand Up @@ -33,26 +33,51 @@ import existingModule from "existing-module";
{
"rules": {
"node/no-missing-import": [2, {
"allowModules": [],
"tryExtensions": [".js", ".json", ".node"]
}]
}
}
```

#### `allowModules`

Some platforms have additional embedded modules.
For example, Electron has `electron` module.

We can specify additional embedded modules with this option.
This option is an array of strings as module names.

```json
{
"rules": {
"node/no-missing-import": [2, {
"allowModules": ["electron"]
}]
}
}
```

#### `tryExtensions`

When an import path does not exist, this rule checks whether or not any of `path.js`, `path.json`, and `path.node` exists.
`tryExtensions` option is the extension list this rule uses at the time.

Default is `[".js", ".json", ".node"]`.

This option can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have this option, but we can set this option at once.
### Shared Settings

The following options can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have the same option, but we can set this option at once.

- `allowModules`
- `tryExtensions`

```json
{
"settings": {
"node": {
"allowModules": ["electron"],
"tryExtensions": [".js", ".json", ".node"]
}
},
Expand Down
29 changes: 27 additions & 2 deletions docs/rules/no-missing-require.md
Expand Up @@ -39,26 +39,51 @@ var foo = require(FOO_NAME);
{
"rules": {
"node/no-missing-require": [2, {
"allowModules": [],
"tryExtensions": [".js", ".json", ".node"]
}]
}
}
```

#### `allowModules`

Some platforms have additional embedded modules.
For example, Electron has `electron` module.

We can specify additional embedded modules with this option.
This option is an array of strings as module names.

```json
{
"rules": {
"node/no-missing-require": [2, {
"allowModules": ["electron"]
}]
}
}
```

#### `tryExtensions`

When an import path does not exist, this rule checks whether or not any of `path.js`, `path.json`, and `path.node` exists.
`tryExtensions` option is the extension list this rule uses at the time.

Default is `[".js", ".json", ".node"]`.

This option can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have this option, but we can set this option at once.
### Shared Settings

The following options can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have the same option, but we can set this option at once.

- `allowModules`
- `tryExtensions`

```json
{
"settings": {
"node": {
"allowModules": ["electron"],
"tryExtensions": [".js", ".json", ".node"]
}
},
Expand Down
21 changes: 21 additions & 0 deletions docs/rules/no-unpublished-import.md
Expand Up @@ -42,13 +42,32 @@ import dependedModule from "depended-module";
{
"rules": {
"node/no-unpublished-import": [2, {
"allowModules": [],
"convertPath": null,
"tryExtensions": [".js", ".json", ".node"]
}]
}
}
```

#### `allowModules`

Some platforms have additional embedded modules.
For example, Electron has `electron` module.

We can specify additional embedded modules with this option.
This option is an array of strings as module names.

```json
{
"rules": {
"node/no-unpublished-import": [2, {
"allowModules": ["electron"]
}]
}
}
```

#### `convertPath`

If we use transpilers (e.g. Babel), perhaps the file path to a source code is never published.
Expand Down Expand Up @@ -92,6 +111,7 @@ Default is `[".js", ".json", ".node"]`.
The following options can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have the same option, but we can set this option at once.

- `allowModules`
- `convertPath`
- `tryExtensions`

Expand All @@ -101,6 +121,7 @@ For Example:
{
"settings": {
"node": {
"allowModules": ["electron"],
"convertPath": {
"src/**/*.jsx": ["^src/(.+?)\\.jsx$", "lib/$1.js"]
},
Expand Down
21 changes: 21 additions & 0 deletions docs/rules/no-unpublished-require.md
Expand Up @@ -44,13 +44,32 @@ var foo = require(FOO_NAME);
{
"rules": {
"node/no-unpublished-require": [2, {
"allowModules": [],
"convertPath": null,
"tryExtensions": [".js", ".json", ".node"]
}]
}
}
```

#### `allowModules`

Some platforms have additional embedded modules.
For example, Electron has `electron` module.

We can specify additional embedded modules with this option.
This option is an array of strings as module names.

```json
{
"rules": {
"node/no-unpublished-require": [2, {
"allowModules": ["electron"]
}]
}
}
```

#### `convertPath`

If we use transpilers (e.g. Babel), perhaps the file path to a source code is never published.
Expand Down Expand Up @@ -94,6 +113,7 @@ Default is `[".js", ".json", ".node"]`.
The following options can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have the same option, but we can set this option at once.

- `allowModules`
- `convertPath`
- `tryExtensions`

Expand All @@ -103,6 +123,7 @@ For Example:
{
"settings": {
"node": {
"allowModules": ["electron"],
"convertPath": {
"src/**/*.jsx": ["^src/(.+?)\\.jsx$", "lib/$1.js"]
},
Expand Down
8 changes: 8 additions & 0 deletions lib/rules/no-missing-import.js
Expand Up @@ -38,6 +38,14 @@ module.exports.schema = [
{
type: "object",
properties: {
allowModules: {
type: "array",
items: {
type: "string",
pattern: "^(?:@[a-zA-Z0-9_]+/)?[a-zA-Z0-9_]+$"
},
uniqueItems: true
},
tryExtensions: {
type: "array",
items: {
Expand Down
8 changes: 8 additions & 0 deletions lib/rules/no-missing-require.js
Expand Up @@ -38,6 +38,14 @@ module.exports.schema = [
{
type: "object",
properties: {
allowModules: {
type: "array",
items: {
type: "string",
pattern: "^(?:@[a-zA-Z0-9_]+/)?[a-zA-Z0-9_]+$"
},
uniqueItems: true
},
tryExtensions: {
type: "array",
items: {
Expand Down
8 changes: 8 additions & 0 deletions lib/rules/no-unpublished-import.js
Expand Up @@ -38,6 +38,14 @@ module.exports.schema = [
{
type: "object",
properties: {
allowModules: {
type: "array",
items: {
type: "string",
pattern: "^(?:@[a-zA-Z0-9_]+/)?[a-zA-Z0-9_]+$"
},
uniqueItems: true
},
convertPath: {
type: "object",
properties: {},
Expand Down
8 changes: 8 additions & 0 deletions lib/rules/no-unpublished-require.js
Expand Up @@ -38,6 +38,14 @@ module.exports.schema = [
{
type: "object",
properties: {
allowModules: {
type: "array",
items: {
type: "string",
pattern: "^(?:@[a-zA-Z0-9_]+/)?[a-zA-Z0-9_]+$"
},
uniqueItems: true
},
convertPath: {
type: "object",
properties: {},
Expand Down
5 changes: 5 additions & 0 deletions lib/util/check-existence.js
Expand Up @@ -14,6 +14,7 @@
var path = require("path");
var resolve = require("resolve");
var exists = require("./exists");
var getAllowModules = require("./get-allow-modules");

//------------------------------------------------------------------------------
// Public Interface
Expand All @@ -31,6 +32,7 @@ var exists = require("./exists");
* @returns {void}
*/
module.exports = function checkForExistence(context, filePath, targets) {
var allowed = getAllowModules(context);
var opts = {basedir: path.dirname(path.resolve(filePath))};

for (var i = 0; i < targets.length; ++i) {
Expand All @@ -42,6 +44,9 @@ module.exports = function checkForExistence(context, filePath, targets) {
continue;
}
}
else if (allowed.indexOf(target.moduleName) !== -1) {
continue;
}
else {
try {
resolve.sync(target.name, opts);
Expand Down
7 changes: 5 additions & 2 deletions lib/util/check-publish.js
Expand Up @@ -13,6 +13,7 @@

var path = require("path");
var assign = require("object-assign");
var getAllowModules = require("./get-allow-modules");
var getConvertPath = require("./get-convert-path");
var getNpmignore = require("./get-npmignore");
var getPackageJson = require("./get-package-json");
Expand All @@ -37,6 +38,7 @@ module.exports = function checkForPublish(context, filePath, targets) {
return;
}

var allowed = getAllowModules(context);
var convertPath = getConvertPath(context);
var basedir = path.dirname(packageInfo.filePath);
var toRelative = function(fullPath) { // eslint-disable-line func-style
Expand All @@ -63,7 +65,8 @@ module.exports = function checkForPublish(context, filePath, targets) {

if (target.moduleName &&
!dependencies[target.moduleName] &&
!devDependencies[target.moduleName]
!devDependencies[target.moduleName] &&
allowed.indexOf(target.moduleName) === -1
) {
context.report({
node: target.node,
Expand All @@ -79,7 +82,7 @@ module.exports = function checkForPublish(context, filePath, targets) {
target = targets[i];

if (target.moduleName ?
!dependencies[target.moduleName] :
(!dependencies[target.moduleName] && allowed.indexOf(target.moduleName) === -1) :
npmignore.match(toRelative(target.filePath))
) {
context.report({
Expand Down
48 changes: 48 additions & 0 deletions lib/util/get-allow-modules.js
@@ -0,0 +1,48 @@
/**
* @author Toru Nagashima
* @copyright 2016 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/

"use strict";

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

var DEFAULT_VALUE = Object.freeze([]);

/**
* Gets `allowModules` property from a given option object.
*
* @param {object|undefined} option - An option object to get.
* @returns {string[]|null} The `allowModules` value, or `null`.
*/
function get(option) {
if (option && option.allowModules && Array.isArray(option.allowModules)) {
return option.allowModules.map(String);
}
return null;
}

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------

/**
* Gets "allowModules" setting.
*
* 1. This checks `options` property, then returns it if exists.
* 2. This checks `settings.node` property, then returns it if exists.
* 3. This returns `[]`.
*
* @param {RuleContext} context - The rule context.
* @returns {string[]} A list of extensions.
*/
module.exports = function getAllowModules(context) {
return (
get(context.options && context.options[0]) ||
get(context.settings && context.settings.node) ||
DEFAULT_VALUE
);
};
9 changes: 9 additions & 0 deletions tests/lib/rules/no-missing-import.js
Expand Up @@ -176,6 +176,15 @@ ruleTester.run("no-missing-import", rule, {
code: "import a from './foo/';",
ecmaFeatures: {modules: true},
parserOptions: {sourceType: "module"}
},

// allow option.
{
filename: fixture("test.js"),
code: "import electron from 'electron';",
options: [{allowModules: ["electron"]}],
ecmaFeatures: {modules: true},
parserOptions: {sourceType: "module"}
}
],
invalid: [
Expand Down

0 comments on commit 23f6fba

Please sign in to comment.