Merge pull request #762 from medayo/resolvePackageJSONConflicts
Using filer with webpack
This commit is contained in:
commit
aacc8061cf
3
AUTHORS
3
AUTHORS
|
@ -5,4 +5,5 @@ Barry Tulchinsky <barry.tulchinsky@gmail.com> (@btulchinsky)
|
||||||
Kieran Sedgwick <kieran.sedgwick@gmail.com> (@sedge)
|
Kieran Sedgwick <kieran.sedgwick@gmail.com> (@sedge)
|
||||||
Yoav Gurevich <ygurevich@ymail.com>
|
Yoav Gurevich <ygurevich@ymail.com>
|
||||||
Gideon Thomas <r.gideonthomas@gmail.com>
|
Gideon Thomas <r.gideonthomas@gmail.com>
|
||||||
Abdirahman Guled <aguled2@myseneca.ca>
|
Abdirahman Guled <aguled2@myseneca.ca>
|
||||||
|
Ben Heidemann <ben@heidemann.co.uk>
|
142
README.md
142
README.md
|
@ -54,6 +54,148 @@ requirejs(['filer'], function(Filer) {...}
|
||||||
var Filer = window.Filer;
|
var Filer = window.Filer;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Webpack
|
||||||
|
|
||||||
|
Filer can be used as a drop-in replacement for the node.js [fs module](http://nodejs.org/api/fs.html) using webpack.
|
||||||
|
|
||||||
|
In order to use filer in place of fs, insert the following into your webpack config:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// webpack.config.js
|
||||||
|
module.exports = {
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'fs': 'filer/shims/fs.js',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then import the node.js [fs module](http://nodejs.org/api/fs.html) as normal
|
||||||
|
and the shim will ensure that calls to fs are appropriately handled by filer.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import fs from 'fs';
|
||||||
|
```
|
||||||
|
|
||||||
|
If any calls are made to fs or fs.promises methods before the file system has been
|
||||||
|
initialised, the shim will automatically delay the call until the file system is ready.
|
||||||
|
|
||||||
|
If you're using filer in a typescript project, the fs shim has the added
|
||||||
|
benefit of allowing you to use the types for the node.js [fs module](http://nodejs.org/api/fs.html),
|
||||||
|
which filer tries to match as closely as possible. Note that some methods from fs are
|
||||||
|
not available, even though typescript will tell you that they are! See [Getting Started](#getting-started)
|
||||||
|
for more details on filers limitations.
|
||||||
|
|
||||||
|
If you wish to use an alternative file system provider in place of the default (IndexedDB), you must also
|
||||||
|
include an alias for this in your webpack config. For example, if you wish to use an "in memory"
|
||||||
|
file system, configure webpack as shown below.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// webpack.config.js
|
||||||
|
module.exports = {
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'fsProvider': 'filer/shims/providers/memory.js',
|
||||||
|
'fs': 'filer/shims/fs.js',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The current options for file system providers are:
|
||||||
|
|
||||||
|
* Default (IndexedDB) - filer/shims/providers/default.js
|
||||||
|
* IndexedDB - filer/shims/providers/default.js
|
||||||
|
* Memory - filer/shims/providers/memory.js
|
||||||
|
|
||||||
|
Though it's technically optional, it is recommended to include an alias for fsProvider in your
|
||||||
|
webpack config. This will prevent webpack from logging unnecessary warnings.
|
||||||
|
|
||||||
|
If you wish to use your own file system provider with the node.js [fs module](http://nodejs.org/api/fs.html)
|
||||||
|
shim, it will be necessary to include an alias for fsProvider which points to your providers implementation.
|
||||||
|
This can be done as follows:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// webpack.config.js
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'fsProvider': path.resolve(__dirname, 'example/dir/provider.js'),
|
||||||
|
'fs': 'filer/shims/fs.js',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The node.js [path module](http://nodejs.org/api/path.html) also has a shim available, which can
|
||||||
|
be applied in a similar manner to the node.js [fs module](http://nodejs.org/api/fs.html) shim.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// webpack.config.js
|
||||||
|
module.exports = {
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'path': 'filer/shims/path.js',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then import the node.js [path module](http://nodejs.org/api/path.html) as normal and the
|
||||||
|
shim will ensure that calls to path are appropriately handled by filer.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import path from 'path';
|
||||||
|
```
|
||||||
|
|
||||||
|
It may be necessary in certain cases to shim the node.js [Buffer object](http://nodejs.org/api/buffer.html). This can be impoerted as follows:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { Buffer } from 'buffer';
|
||||||
|
```
|
||||||
|
|
||||||
|
As such it can be shimmed in much the same way as path and fs:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// webpack.config.js
|
||||||
|
module.exports = {
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'buffer': 'filer/shims/buffer.js',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
However, the Buffer object is globally defined in a node environment and many third party libraries will not import (or require) it.
|
||||||
|
Using the resolve alias alone will be ineffective in such cases. Instead we must expand our webpack config to use webpacks
|
||||||
|
[provide plugin](https://webpack.js.org/plugins/provide-plugin/), which will automatically load the module without the need for an import
|
||||||
|
or require. This can be implemented as follows:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// webpack.config.js
|
||||||
|
const webpack = require('webpack');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'buffer': 'filer/shims/buffer.js',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.ProvidePlugin({
|
||||||
|
Buffer: 'buffer',
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This will, in effect, make the Buffer object shim globally available in the same way that the node.js
|
||||||
|
[Buffer object](http://nodejs.org/api/buffer.html) is in a node environment.
|
||||||
|
|
||||||
### Getting Started
|
### Getting Started
|
||||||
|
|
||||||
Filer is as close to the node.js [fs module](http://nodejs.org/api/fs.html) as possible,
|
Filer is as close to the node.js [fs module](http://nodejs.org/api/fs.html) as possible,
|
||||||
|
|
|
@ -2,10 +2,14 @@ module.exports = function(config) {
|
||||||
config.set({
|
config.set({
|
||||||
singleRun: true,
|
singleRun: true,
|
||||||
basePath: '',
|
basePath: '',
|
||||||
files: ['tests/dist/index.js'],
|
files: [
|
||||||
|
'node_modules/regenerator-runtime/runtime.js',
|
||||||
|
'tests/dist/index.js'
|
||||||
|
],
|
||||||
frameworks: ['mocha', 'chai'],
|
frameworks: ['mocha', 'chai'],
|
||||||
reporters: ['mocha', 'summary'],
|
reporters: ['mocha', 'summary'],
|
||||||
client: {
|
client: {
|
||||||
|
captureConsole: true,
|
||||||
mocha: {
|
mocha: {
|
||||||
ui: 'bdd',
|
ui: 'bdd',
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
"minimatch": "^3.0.4"
|
"minimatch": "^3.0.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"regenerator-runtime": "^0.13.7",
|
||||||
"chai": "^4.3.0",
|
"chai": "^4.3.0",
|
||||||
"chai-datetime": "^1.8.0",
|
"chai-datetime": "^1.8.0",
|
||||||
"eslint": "^7.20.0",
|
"eslint": "^7.20.0",
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
const { Buffer } = require('../src/index');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
__esModule: true,
|
||||||
|
default: Buffer,
|
||||||
|
Buffer,
|
||||||
|
};
|
|
@ -0,0 +1,56 @@
|
||||||
|
const { FileSystem } = require('../src/index');
|
||||||
|
|
||||||
|
let Provider;
|
||||||
|
try {
|
||||||
|
Provider = require('fsProvider');
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
Provider = require('./providers/default');
|
||||||
|
}
|
||||||
|
|
||||||
|
const provider = new Provider();
|
||||||
|
|
||||||
|
let onFsReady;
|
||||||
|
let onFsError;
|
||||||
|
|
||||||
|
let fsReady = new Promise((resolve, reject) => {
|
||||||
|
onFsReady = resolve;
|
||||||
|
onFsError = reject;
|
||||||
|
});
|
||||||
|
|
||||||
|
var fsInstance = new FileSystem({ provider }, (err) => {
|
||||||
|
if (err) {
|
||||||
|
onFsError(err);
|
||||||
|
} else {
|
||||||
|
onFsReady(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const fsPromises = new Proxy(fsInstance.promises, {
|
||||||
|
get(target, prop) {
|
||||||
|
return async (...args) => {
|
||||||
|
await fsReady;
|
||||||
|
return await target[prop](...args);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const fs = new Proxy(fsInstance, {
|
||||||
|
get(target, prop) {
|
||||||
|
if (prop === 'promises') {
|
||||||
|
return fsPromises;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (...args) => {
|
||||||
|
(async () => {
|
||||||
|
await fsReady;
|
||||||
|
target[prop](...args);
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
__esModule: true,
|
||||||
|
default: fs,
|
||||||
|
};
|
|
@ -0,0 +1,6 @@
|
||||||
|
const { path } = require('../src/index');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
__esModule: true,
|
||||||
|
default: path,
|
||||||
|
};
|
|
@ -0,0 +1,2 @@
|
||||||
|
const { Default } = require('../../src/providers/index');
|
||||||
|
module.exports = Default;
|
|
@ -0,0 +1,2 @@
|
||||||
|
const IndexedDB = require('../../src/providers/indexeddb');
|
||||||
|
module.exports = IndexedDB;
|
|
@ -0,0 +1,2 @@
|
||||||
|
const Memory = require('../../src/providers/memory');
|
||||||
|
module.exports = Memory;
|
|
@ -3,6 +3,11 @@
|
||||||
* get them running by default.
|
* get them running by default.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Shims
|
||||||
|
require('./spec/shims/fs.spec');
|
||||||
|
require('./spec/shims/path.spec');
|
||||||
|
require('./spec/shims/buffer.spec');
|
||||||
|
|
||||||
// Filer
|
// Filer
|
||||||
require('./spec/filer.spec');
|
require('./spec/filer.spec');
|
||||||
require('./spec/filer.buffer.spec.js');
|
require('./spec/filer.buffer.spec.js');
|
||||||
|
|
|
@ -52,11 +52,13 @@ function shimIndexedDB(fn) {
|
||||||
global.indexedDB = require('fake-indexeddb');
|
global.indexedDB = require('fake-indexeddb');
|
||||||
}
|
}
|
||||||
|
|
||||||
fn();
|
var result = fn();
|
||||||
|
|
||||||
if(addShim) {
|
if(addShim) {
|
||||||
delete global.indexedDB;
|
delete global.indexedDB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setup(callback) {
|
function setup(callback) {
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
'use strict';
|
||||||
|
const expect = require('chai').expect;
|
||||||
|
const bufferDefault = require('../../../shims/buffer').default;
|
||||||
|
const bufferNamed = require('../../../shims/buffer').Buffer;
|
||||||
|
const bufferActual = require('../../../src/index').Buffer;
|
||||||
|
|
||||||
|
describe.only('path shim', () => {
|
||||||
|
it('default export should be defined', () => {
|
||||||
|
expect(bufferDefault).to.not.be.undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('named export should be defined', () => {
|
||||||
|
expect(bufferNamed).to.not.be.undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('default export should be re-exposing Buffer', () => {
|
||||||
|
expect(bufferDefault).to.equal(bufferActual);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('named export should be re-exposing Buffer', () => {
|
||||||
|
expect(bufferNamed).to.equal(bufferActual);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,44 @@
|
||||||
|
'use strict';
|
||||||
|
const expect = require('chai').expect;
|
||||||
|
const utils = require('../../lib/test-utils');
|
||||||
|
const fs = utils.shimIndexedDB(() => require('../../../shims/fs').default);
|
||||||
|
|
||||||
|
describe.only('fs shim', () => {
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(fs).to.not.be.undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be an object', () => {
|
||||||
|
expect(typeof fs).to.equal('object');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a function when accessing fs.writeFile', () => {
|
||||||
|
expect(typeof fs.writeFile).to.equal('function');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call callback when calling fs.writeFile', (done) => {
|
||||||
|
fs.writeFile('/test.txt', 'test', function(err) {
|
||||||
|
if(err) throw err;
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an object when accessing fs.promises', () => {
|
||||||
|
expect(typeof fs.promises).to.equal('object');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a function when accessing fs.promises.writeFile', () => {
|
||||||
|
expect(typeof fs.promises.writeFile).to.equal('function');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a promise which resolves when calling fs.promises.writeFile', (done) => {
|
||||||
|
const writeFilePromise = fs.promises.writeFile('/test2.txt', '');
|
||||||
|
expect(writeFilePromise instanceof Promise).to.equal(true);
|
||||||
|
writeFilePromise.then(() => {
|
||||||
|
done();
|
||||||
|
}).catch((err) => {
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
const expect = require('chai').expect;
|
||||||
|
const path = require('../../../shims/path').default;
|
||||||
|
const pathActual = require('../../../src/index').path;
|
||||||
|
|
||||||
|
describe.only('path shim', () => {
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(path).to.not.be.undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be re-exposing path', () => {
|
||||||
|
expect(path).to.equal(pathActual);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue