diff --git a/README.md b/README.md index 61e72bc..a3ff64a 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,103 @@ requirejs(['filer'], function(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 sytem 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'; +``` + ### Getting Started Filer is as close to the node.js [fs module](http://nodejs.org/api/fs.html) as possible, diff --git a/shims/fs.js b/shims/fs.js new file mode 100644 index 0000000..832847a --- /dev/null +++ b/shims/fs.js @@ -0,0 +1,56 @@ +const { FileSystem } = require('../src/index'); + +let Provider; +try { + Provider = require('fsprovider'); +} +catch { + 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, +}; diff --git a/shims/path.js b/shims/path.js new file mode 100644 index 0000000..ffd0088 --- /dev/null +++ b/shims/path.js @@ -0,0 +1,6 @@ +const path = require("./path.js"); + +module.exports = { + __esModule: true, + default: path, +}; diff --git a/shims/providers/default.js b/shims/providers/default.js new file mode 100644 index 0000000..2ba8094 --- /dev/null +++ b/shims/providers/default.js @@ -0,0 +1,2 @@ +const { Default } = require('../../src/providers/index'); +module.exports = Default; \ No newline at end of file diff --git a/shims/providers/indexeddb.js b/shims/providers/indexeddb.js new file mode 100644 index 0000000..6e01dc1 --- /dev/null +++ b/shims/providers/indexeddb.js @@ -0,0 +1,2 @@ +const IndexedDB = require('../../src/providers/indexeddb'); +module.exports = IndexedDB; \ No newline at end of file diff --git a/shims/providers/memory.js b/shims/providers/memory.js new file mode 100644 index 0000000..c33cc34 --- /dev/null +++ b/shims/providers/memory.js @@ -0,0 +1,2 @@ +const Memory = require('../../src/providers/memory'); +module.exports = Memory; \ No newline at end of file