Организация требований и перемещение их в документ.
Я организую код в приложении. Операторы require не организованы, поэтому я создал этот код для сортировки и добавления их в верхней части страницы.
Кодмод работает, почти идеально. У меня есть некоторые сомнения:
- Это нормально, или есть более правильный способ использования API?
- как я могу держать пустую строку между
sourceStart
(все требуется) и остальная часть исходного кода? - Можно ли использовать аналогичный подход в импорте ES6? (т.е. отсортировать их с помощью jscodeshift)
Мой начальный код:
var path = require('path');
var stylus = require('stylus');
var express = require('express');
var router = express.Router();
var async = require('async');
let restOfCode = 'foo';
Мой кодмод:
let requires = j(file.source).find(j.CallExpression, {
"callee": {
"name": "require"
}
}).closest(j.VariableDeclarator);
let sortedNames = requires.__paths.map(node => node.node.id.name).sort(sort); // ["async", "express", "path", "stylus"]
let sortedRequires = [];
requires.forEach(r => {
let index = sortedNames.indexOf(r.node.id.name);
sortedRequires[index] = j(r).closest(j.VariableDeclaration).__paths[0]; // <- feels like a hack
});
let sourceStart = j(sortedRequires).toSource();
let sourceRest = j(file.source).find(j.CallExpression, {
"callee": {
"name": "require"
}
}).closest(j.VariableDeclaration)
.replaceWith((vD, i) => {
// return nothing, it will be replaced on top of document
})
.toSource();
return sourceStart.concat(sourceRest).join('\n'); // is there a better way than [].concat(string).join(newLine) ?
И результат, который я получил:
var async = require('async');
var express = require('express');
var path = require('path');
var stylus = require('stylus');
var router = express.Router(); // <- I would expect a empty line before this one
let restOfCode = 'foo';
1 ответ
Это нормально, или есть более правильный способ использования API?
Вы не должны получать доступ __paths
непосредственно. Если вам нужен доступ ко всем NodePaths, вы можете использовать .paths()
метод. Если вы хотите получить доступ к узлам AST, используйте .nodes()
,
Например, отображение будет просто
let sortedNames = requires.nodes()(node => node.id.name).sort(sort);
как я могу держать пустую строку между
sourceStart
(все требуется) и остальная часть исходного кода?
Нет действительно хорошего способа сделать это. Смотрите эту связанную проблему переделки. Надеюсь, это станет проще с CST.
Можно ли использовать аналогичный подход в импорте ES6? (т.е. отсортировать их с помощью jscodeshift)
Конечно.
FWIW, вот моя версия (на основе вашей первой версии):
export default function transformer(file, api) {
const j = api.jscodeshift;
const sort = (a, b) => a.declarations[0].id.name.localeCompare(
b.declarations[0].id.name
);
const root = j(file.source);
const requires = root
.find(j.CallExpression, {"callee": {"name": "require"}})
.closest(j.VariableDeclaration);
const sortedRequires = requires.nodes().sort(sort);
requires.remove();
return root
.find(j.Statement)
.at(0)
.insertBefore(sortedRequires)
.toSource();
};
}