Awesome
eslint-plugin-move-files
Move and rename files while keeping imports up to date
Table of Contents
- š£ Summary
- š© Installation
- š¤« Caveats
- āļø Configuration
- š¤ Target Problem
- ššæāāļø Getting Help
- š Other Projects
- š¤ Author
š£ Summary
- Move and rename files in bulk.
- Update all
import
declarations andrequire
statements in the codebase. - Standardise where certain files should be named and located.
- Automatically move new files to the correct locations.
š© Installation
npm install --save-dev eslint eslint-plugin-move-files
š¤« Caveats
- This plugin is in alpha, more testing is needed on real projects.
- It is best to run this rule on its own to avoid false-positives from plugins
such as
eslint-plugin-imports
while files are being moved but files dependending on them have not yet been updated. This is necessary because the order which rules and files will run is not predictable or guaranteed.
āļø Configuration
npm Scripts
It is recommended to run this plugin on its own, before running the other ESLint
Rules in your project. In this example you would run npm run lint
to achieve
this:
{
"scripts": {
"lint:fs": "eslint --fix --config .eslintrc-fs.js --no-inline-config 'src/**/*.js' 'test/**/*.js'",
"lint:js": "eslint --fix --config .eslintrc.js 'src/**/*.js' 'test/**/*.js'",
"lint": "npm run lint:fs && npm run lint:js"
}
}
ESLint
These changes relate to the .eslintrc
file explained in
Configuring ESLint. You will
need to ensure 'move-files'
is included in the plugins
array and that a
'move-files/move-files'
property of the rules
object is present and matches
the structure described below.
{
"root": true,
"parserOptions": {
"ecmaVersion": 2019,
"sourceType": "module"
},
"plugins": ["move-files"],
"rules": {
"move-files/move-files": [
"error",
{
"files": {
// rename a file in-place
"./src/rename-me.js": "./renamed.js",
// move a file into a sibling of its current directory
"./src/server.test.js": "../test/server.js",
// convert a flat directory of files into module folders
"./src/services/*.js": "./{name}/index.js",
// use .jsx extension in all React components
"./src/components/**/*.js": "./{name}.jsx",
// locate tests alongside source
"./test/*.js": "{rootDir}/src/{name}.spec.js",
"./test/*/*.js": "{rootDir}/src/{..}/{name}.spec.js",
"./test/*/*/*.js": "{rootDir}/src/{...}/{..}/{name}.spec.js",
"./test/*/*/*/*.js": "{rootDir}/src/{....}/{...}/{..}/{name}.spec.js",
"./test/*/*/*/*/*.js": "{rootDir}/src/{.....}/{....}/{...}/{..}/{name}.spec.js",
"./test/*/*/*/*/*/*.js": "{rootDir}/src/{......}/{.....}/{....}/{...}/{..}/{name}.spec.js",
"./test/*/*/*/*/*/*/*.js": "{rootDir}/src/{.......}/{......}/{.....}/{....}/{...}/{..}/{name}.spec.js"
}
}
]
}
}
files
option
files
is an object whose keys define the Sources (which files should move)
and whose values define the Destinations (where the files should move to).
- Sources can match multiple files via the use of "Globs".
- Sources are resolved relative to the
process.cwd()
root directory of your project. - Destinations are resolved relative to each matched source file.
- Destinations can optionally use tokens such as
{name}
or{ext}
to interpolate values parsed from the Source path.
String Interpolation
Using src/lib/module.spec.js
as an example, the following data would be
available:
{
"rootDir": "/path/to/project",
"dir": "src/lib",
"base": "module.spec.js",
"name": "module",
"ext": "spec.js",
"dirs": ["src", "lib"],
"exts": ["spec", "js"],
"ancestors": ["lib", "src"]
}
This dataset can be read using the following tokens. A destination of
'{rootDir}/test/{ancestors.0}/{name}.js'
for example would move this file to
/path/to/project/test/lib/module.js
.
Token | Value |
---|---|
{rootDir} | /path/to/project |
{dir} | src/lib |
{base} or {.} | module.spec.js |
{name} | module |
{ext} | spec.js |
{dirs.0} | src |
{dirs.1} | lib |
{exts.0} | spec |
{exts.1} | js |
{ancestors.0} or {..} | lib |
{ancestors.1} or {...} | src |
š¤ Target Problem
Moving files with increased confidence
Moving and renaming files in a large codebase can be time-consuming and error-prone due to:
- The large number of files to search for and edit
import
declarations in. - The high probability of conflicts as you
git merge
frommaster
. - The high probability of conflicts in other branches once yours is merged.
Maintaining a standard file structure
Imagine that you want to migrate your codebase from being organised by role to be organised by feature. Once you've done the work of moving everything into the new structure, you want Contributors to follow the new approach rather than the old, and you want it to be easy to fix if they don't.
Organised by Role
āāā fixtures
ā āāā billing.js
āāā resolvers
ā āāā billing.js
āāā schema
āāā billing.js
Organised by Feature
āāā billing
āāā fixtures.js
āāā resolvers.js
āāā schema.js
<!-- LINKS -->
ššæāāļø Getting Help
Get help with issues by creating a Bug Report or discuss ideas by opening a Feature Request.
š Other Projects
If you find my Open Source projects useful, please share them ā¤ļø
- eslint-formatter-git-log<br>ESLint Formatter featuring Git Author, Date, and Hash
- eslint-plugin-prefer-arrow-functions<br>Convert functions to arrow functions
- ImageOptim-CLI<br>Automates ImageOptim, ImageAlpha, and JPEGmini for Mac to make batch optimisation of images part of your automated build process.
- Jasmine-Matchers<br>Write Beautiful Specs with Custom Matchers
- karma-benchmark<br>Run Benchmark.js over multiple Browsers, with CI compatible output
- self-help<br>Interactive Q&A Guides for Web and the Command Line
- syncpack<br>Manage multiple package.json files, such as in Lerna Monorepos and Yarn Workspaces
š¤ Author
<img src="https://www.gravatar.com/avatar/acdf106ce071806278438d8c354adec8?s=100" align="left">I'm Jamie Mason from Leeds in England, I began Web Design and Development in 1999 and have been Contracting and offering Consultancy as Fold Left Ltd since 2012. Who I've worked with includes Sky Sports, Sky Bet, Sky Poker, The Premier League, William Hill, Shell, Betfair, and Football Clubs including Leeds United, Spurs, West Ham, Arsenal, and more.
<div align="center"> </div> <!-- images --> <!-- links -->