Skip to content

Commit

Permalink
Windows path fix
Browse files Browse the repository at this point in the history
Hash filename option added
Unit test improved
Readme update
  • Loading branch information
ahalimkara committed Dec 2, 2017
1 parent 73331cb commit d6c06af
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 30 deletions.
34 changes: 31 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ Original plugin's functionality is still working.

- [About](#about)
- [Installation](#installation)
- [Options](#options)
- [Usage](#usage)
- [via babelrc](#via-babelrc)
- [via Node API](#via-node-api)
- [via JavaScript](#via-javascript)

## About

Expand All @@ -23,7 +24,7 @@ This helps when doing _isomorphic_ / server-rendered applications.
import image from './path/to/icon.png';
const image1 = require('./path/to/icon.svg');

// icon.png and icon.svg will be copied to project's root under static folder
// icon.png and icon.svg will be copied to project's root under baseDir (defaults to "/static") folder
// and code will be transformed to:

const image = '/static/path/to/icon.png';
Expand All @@ -46,6 +47,33 @@ See the spec for more [examples](https://github.com/ahalimkara/babel-plugin-impo
$> npm install babel-plugin-import-static-files --save
```

## Options

Default options:
```json
{
"baseDir": "/static",
"hash": false,
"extensions": [
".gif",
".jpeg",
".jpg",
".png",
".svg"
]
}
```

When hash is true (useful for assets caching):
```js
import image from './path/to/icon.png';

// icon.png will be copied to project's root under baseDir (defaults to "/static") folder
// and code will be transformed to:

const image = '/static/icon-[hash].png';
```

## Usage

### via .babelrc
Expand All @@ -69,7 +97,7 @@ or if you will use cdn
}
```

### via Node API
### via JavaScript

```js
require("babel-core").transform("code", {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"lint": "eslint --ext js src test/**/*.spec.*",
"test": "cross-env NODE_ENV=test npm run test:run",
"test:run": "nyc --reporter=text-summary mocha 'test/**/*.spec.js'",
"test:watch": "npm run test -- -- --watch"
"test:watch": "npm run test -- -- --watch",
"build:watch": "npm run build -- --watch"
},
"repository": {
"type": "git",
Expand Down
11 changes: 8 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {dirname, extname, resolve} from'path';
import path, { dirname, extname, resolve } from 'path';
import transform from './transform';

export const defaultOptions = {
baseDir: '/static',
hash: false,
extensions: [
'.gif',
'.jpeg',
Expand All @@ -14,18 +15,22 @@ export const defaultOptions = {

const applyTransform = (p, t, state, value, calleeName) => {
const ext = extname(value);
const options = Object.assign({}, defaultOptions, state.opts);
let options = Object.assign({}, defaultOptions, state.opts);


if (options.extensions && options.extensions.indexOf(ext) >= 0) {
const dir = dirname(resolve(state.file.opts.filename));
const absPath = resolve(dir, value);

if (options.baseDir) {
options.baseDir = options.baseDir.replace(/[\/\\]+/g, path.sep);
}

transform(p, t, state, options, absPath, calleeName);
}
}

export function transformImportsInline({types: t}) {
export function transformImportsInline({ types: t }) {
return {
visitor: {
ImportDeclaration(p, state) {
Expand Down
27 changes: 14 additions & 13 deletions src/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@ import path from 'path';

function getHash(str) {
return crypto
.createHash('sha1')
.createHash('md5')
.update(str, 'utf8')
.digest('hex')
.slice(0, 8);
.digest('hex');
}

function getFile(state, absPath, opts) {
const root = state.file.opts.sourceRoot || process.cwd();
let file = absPath.replace(root, '');
const root = state.file.opts.sourceRoot || process.cwd()
let file

if (opts.hash === true) {
const content = fs.readFileSync(absPath, 'utf8')
const ext = path.extname(absPath)
file = path.basename(absPath, ext) + '-' + getHash(content) + ext
} else {
file = path.sep + absPath.substr(root.length).replace(/^[\/\\]+/, '')
}

if (opts.baseDir) {
file = path.join(opts.baseDir, file);
file = path.sep + path.join(opts.baseDir, file).replace(/^[\/\\]+/, '')
fs.copySync(absPath, path.join(root, file))
}

Expand All @@ -37,14 +44,8 @@ const getVariableName = (p) => {

export default (p, t, state, opts, absPath, calleeName) => {
const file = getFile(state, absPath, opts);
let hash = '';

if (opts.hash === 1) {
const content = fs.readFileSync(absPath, 'utf8').trim();
hash = '?' + getHash(content);
}

const uri = `${opts.baseUri || ''}${file}${hash}`;
const uri = `${opts.baseUri || ''}${file}`;

if (calleeName === 'require') {
p.replaceWith(t.StringLiteral(uri));
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/import-image.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import test from '../../some/assets/deep/folder/assets/path/to/icon.svg';
import test from '../icon.svg';
2 changes: 1 addition & 1 deletion test/fixtures/require-image.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
const test = require('../../some/assets/deep/folder/assets/path/to/icon.svg');
const test = require('../icon.svg');
22 changes: 14 additions & 8 deletions test/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from 'path';
import {expect} from 'chai';
import { expect } from 'chai';
import transformCode from './transformCode';

function getFixtures(name) {
Expand All @@ -14,33 +14,39 @@ describe('index', function () {

it('should replace import statements with uri', function () {
const result = transformCode(getFixtures('import-image.js'), baseConfig).code;
expect(result).to.equal('const test = \'http://cdn.address/assets/path/to/icon.svg\';');
expect(result).to.equal('const test = \'http://cdn.address/assets/test/icon.svg\';');
});

it('should replace import statements with uri and hash of content', function () {
const config = Object.assign({}, baseConfig, {
hash: 1,
baseDir: '/'
hash: true,
});
const result = transformCode(getFixtures('import-uri-hash.js'), config).code;
expect(result).to.equal('const test = \'http://cdn.address/icon.svg?57e1ea98\';');
expect(result).to.equal('const test = \'http://cdn.address/assets/icon-8e5397281d54f75de5cb6f77d1f4bcc8.svg\';');
});

it('should replace import statements with uri when base uri and dir not defined', function () {
const result = transformCode(getFixtures('import-image.js')).code;
expect(result).to.equal('const test = \'icon.svg\';');
expect(result).to.equal('const test = \'/static/test/icon.svg\';');
});

it('should replace import statements with uri when base dir not defined', function () {
const result = transformCode(getFixtures('import-image.js'), {
baseUri: baseConfig.baseUri
}).code;
expect(result).to.equal('const test = \'http://cdn.address/icon.svg\';');
expect(result).to.equal('const test = \'http://cdn.address/static/test/icon.svg\';');
});

it('should replace import statements with base dir for windows path', function () {
const result = transformCode(getFixtures('import-image.js'), {
baseDir: 'static\\media'
}).code;
expect(result).to.equal('const test = \'/static/media/test/icon.svg\';');
});

it('should replace require statements with uri', function () {
const result = transformCode(getFixtures('require-image.js'), baseConfig).code;
expect(result).to.equal('const test = \'http://cdn.address/assets/path/to/icon.svg\';');
expect(result).to.equal('const test = \'http://cdn.address/assets/test/icon.svg\';');
});

it('should do nothing when imports have no extensions', function () {
Expand Down

0 comments on commit d6c06af

Please sign in to comment.