Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
klzns committed Mar 13, 2017
0 parents commit e12af76
Show file tree
Hide file tree
Showing 17 changed files with 527 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
.vscode
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
language: node_js
node_js:
- '6'
- '4'
85 changes: 85 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# parse-es6-imports

> Parse ES6 imports from a string
## Install

```sh
$ npm install parse-es6-imports --save
```

### Usage

```js
const parseImports = require('parse-es6-imports')

const code = `
import defaultA from './moduleA'
import defaultB, { namedB } from './moduleB'
import { namedC } from './moduleC'
import { namedD as otherName } from './moduleD'
import * as moduleE from './moduleE'
import './moduleF'
`

const result = parseImports(code)

console.log(JSON.stringify(result, null, 2))

// {
// "defaultImport": "defaultA",
// "namedImports": [],
// "starImport": null,
// "fromModule": "./moduleA"
// },
// {
// "defaultImport": "defaultB",
// "namedImports": [
// {
// "name": "namedB",
// "value": "namedB"
// }
// ],
// "starImport": null,
// "fromModule": "./moduleB"
// },
// {
// "defaultImport": null,
// "namedImports": [
// {
// "name": "namedC",
// "value": "namedC"
// }
// ],
// "starImport": null,
// "fromModule": "./moduleC"
// },
// {
// "defaultImport": null,
// "namedImports": [
// {
// "name": "namedD",
// "value": "otherName"
// }
// ],
// "starImport": null,
// "fromModule": "./moduleD"
// },
// {
// "defaultImport": null,
// "namedImports": [],
// "starImport": "moduleE",
// "fromModule": "./moduleE"
// },
// {
// "defaultImport": null,
// "namedImports": [],
// "starImport": null,
// "fromModule": "./moduleF"
// }
// ]
```

## License

MIT
68 changes: 68 additions & 0 deletions example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const parseImports = require('./index')

const code = `
import defaultA from './moduleA'
import defaultB, { namedB } from './moduleB'
import { namedC } from './moduleC'
import { namedD as otherName } from './moduleD'
import * as moduleE from './moduleE'
import './moduleF'
`

const result = parseImports(code)

console.log(JSON.stringify(result, null, 2))

// [
// {
// "defaultImport": "defaultA",
// "namedImports": [],
// "starImport": null,
// "fromModule": "./moduleA"
// },
// {
// "defaultImport": "defaultB",
// "namedImports": [
// {
// "name": "namedB",
// "value": "namedB"
// }
// ],
// "starImport": null,
// "fromModule": "./moduleB"
// },
// {
// "defaultImport": null,
// "namedImports": [
// {
// "name": "namedC",
// "value": "namedC"
// }
// ],
// "starImport": null,
// "fromModule": "./moduleC"
// },
// {
// "defaultImport": null,
// "namedImports": [
// {
// "name": "namedD",
// "value": "otherName"
// }
// ],
// "starImport": null,
// "fromModule": "./moduleD"
// },
// {
// "defaultImport": null,
// "namedImports": [],
// "starImport": "moduleE",
// "fromModule": "./moduleE"
// },
// {
// "defaultImport": null,
// "namedImports": [],
// "starImport": null,
// "fromModule": "./moduleF"
// }
// ]
36 changes: 36 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const parseImport = require('./parser')

module.exports = function parse(str) {
const lines = str.split('\n')
const results = []

for (let i = 0; i < lines.length; i++) {
const line = lines[i]

if (isLineWithComment(line) || isEmptyLine(line)) {
continue
}

if (isLineWithImport(line)) {
const result = parseImport(line)
results.push(result)
continue
}

break
}

return results
}

function isEmptyLine(line) {
return line.trim() === ''
}

function isLineWithImport(line) {
return line.trim().indexOf('import') === 0
}

function isLineWithComment(line) {
return line.trim().indexOf('//') === 0 || line.trim().indexOf('/*') === 0
}
27 changes: 27 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "parse-es6-imports",
"version": "0.1.0",
"description": "Parse ES6 imports from a string",
"main": "index.js",
"scripts": {
"test": "jest"
},
"keywords": [
"parse",
"es6",
"import",
"imports",
"string"
],
"author": {
"name": "Breno Calazans",
"email": "brenocalazans@gmail.com"
},
"engines": {
"node": ">=4"
},
"license": "MIT",
"devDependencies": {
"jest": "^19.0.2"
}
}
130 changes: 130 additions & 0 deletions parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
const IMPORT_KEYWORD = 'import'
const FROM_KEYWORD = 'from'
const AS_KEYWORD = 'as'
const NAMED_IMPORTS_OPEN_TOKEN = '{'
const NAMED_IMPORTS_CLOSE_TOKEN = '}'

module.exports = function parseImport(line) {
const trimmedLine = line.trim()
const lineWithoutImport = removeImportKeyword(trimmedLine)

if (!hasFrom(lineWithoutImport)) {
const fromModule = removeQuotesAndSemicolon(lineWithoutImport)
return {
defaultImport: null,
namedImports: [],
starImport: null,
fromModule,
}
}

const [beforeFrom, afterFrom] = lineWithoutImport.split(FROM_KEYWORD)
const fromModule = removeQuotesAndSemicolon(afterFrom)

const defaultOrStarImportStr = getDefaultOrStarImportStr(beforeFrom)
const namedImportStr = getNamedImportsStr(beforeFrom)

const { defaultImport, starImport } = parseDefaultOrStarImport(defaultOrStarImportStr)
const namedImports = parseNamedImports(namedImportStr)

return {
defaultImport,
namedImports,
starImport,
fromModule,
}
}

function removeImportKeyword(line) {
return line.slice(IMPORT_KEYWORD.length)
}

function hasFrom(line) {
return line.indexOf(` ${FROM_KEYWORD} `) !== -1
}

function getDefaultOrStarImportStr(importVariables) {
if (containsNamedImports(importVariables)) {
const [beforeNamedImports] = importVariables.split(NAMED_IMPORTS_OPEN_TOKEN)
return beforeNamedImports
}

return importVariables
}

function getNamedImportsStr(importVariables) {
if (containsNamedImports(importVariables)) {
const [_, afterNamedImports] = importVariables.split(NAMED_IMPORTS_OPEN_TOKEN)
return afterNamedImports.replace(NAMED_IMPORTS_CLOSE_TOKEN, '')
}

return null
}

function containsNamedImports(str) {
return str.indexOf(NAMED_IMPORTS_OPEN_TOKEN) !== -1 &&
str.indexOf(NAMED_IMPORTS_CLOSE_TOKEN) !== -1
}

function parseDefaultOrStarImport(str) {
const noDefaultOrStarImport = {
defaultImport: null,
starImport: null,
}

const cleanStr = str.trim().replace(',', '')

if (cleanStr === '') {
return noDefaultOrStarImport
}

if (hasAs(cleanStr)) {
const { value } = parseAs(cleanStr)
return {
defaultImport: null,
starImport: value,
}
}

return {
defaultImport: cleanStr,
starImport: null,
}
}

function parseNamedImports(namedImportsStr) {
if (!namedImportsStr) return []

const namedImportsValues = namedImportsStr.split(',')
return namedImportsValues.map(mapNameAndValue)
}

function mapNameAndValue(str) {
const trimmedStr = str.trim()

if (hasAs(trimmedStr)) {
return parseAs(trimmedStr)
}

return {
name: trimmedStr,
value: trimmedStr,
}
}

function hasAs(str) {
return str.indexOf(` ${AS_KEYWORD} `) !== -1
}

function parseAs(str) {
const [ name, value ] = str.split(` ${AS_KEYWORD} `)

return {
name,
value,
}
}

function removeQuotesAndSemicolon(str) {
return str.trim().replace(/[\;\'\"]/g, '')
}
5 changes: 5 additions & 0 deletions tests/fixtures/as-import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { namedImport as otherName } from './fileA'

const Foo = () {}

export default Foo
5 changes: 5 additions & 0 deletions tests/fixtures/default-and-named-imports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import defaultImport, { firstNamedImport, secondNamedImport } from './fileA'

const Foo = () {}

export default Foo
5 changes: 5 additions & 0 deletions tests/fixtures/default-import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import moduleA from './fileA'

const Foo = () {}

export default Foo
5 changes: 5 additions & 0 deletions tests/fixtures/just-file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import './fileA'

const Foo = () {}

export default Foo
Loading

0 comments on commit e12af76

Please sign in to comment.