Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make the loader async #537

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@
],
"main": "lib/index.js",
"engines": {
"node": ">=4"
"node": ">= 4"
},
"dependencies": {
"find-cache-dir": "^1.0.0",
"loader-utils": "^1.0.2",
"mkdirp": "^0.5.1"
},
"peerDependencies": {
"@babel/core": "7 || ^7.0.0-beta || ^7.0.0-rc",
"webpack": "2 || 3"
"@babel/core": "^7.0.0 || ^7.0.0-rc || ^7.0.0-beta.32",
"webpack": "^2.0.0 || ^3.0.0"
},
"devDependencies": {
"@babel/cli": "7.0.0-beta.5",
"@babel/core": "7.0.0-beta.5",
"@babel/preset-env": "7.0.0-beta.5",
"@babel/cli": "7.0.0-beta.32",
"@babel/core": "7.0.0-beta.32",
"@babel/preset-env": "7.0.0-beta.32",
"ava": "0.23.0",
"babel-eslint": "^8.0.0",
"babel-plugin-istanbul": "^4.0.0",
Expand All @@ -44,7 +44,7 @@
"scripts": {
"clean": "rimraf lib/",
"build": "babel src/ --out-dir lib/",
"format": "prettier --write --trailing-comma all \"src/**/*.js\" \"test/**/*.test.js\" \"test/helpers/*.js\" && prettier --write --trailing-comma es5 \"scripts/*.js\"",
"format": "prettier --write --trailing-comma all 'src/**/*.js' 'test/**/*.test.js' 'test/helpers/*.js' && prettier --write --trailing-comma es5 'scripts/*.js'",
"lint": "eslint src test",
"precommit": "lint-staged",
"prepublish": "yarn run clean && yarn run build",
Expand Down
35 changes: 35 additions & 0 deletions src/Error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const STRIP_FILENAME_RE = /^[^:]+: /;

const format = err => {
if (err instanceof SyntaxError) {
err.name = "SyntaxError";
err.message = err.message.replace(STRIP_FILENAME_RE, "");

err.hideStack = true;
} else if (err instanceof TypeError) {
err.name = null;
err.message = err.message.replace(STRIP_FILENAME_RE, "");

err.hideStack = true;
}

return err;
};

class LoaderError extends Error {
constructor(err) {
super();

const { name, message, codeFrame, hideStack } = format(err);

this.name = "BabelLoaderError";

this.message = `${name ? `${name}: ` : ""}${message}\n\n${codeFrame}\n`;

this.hideStack = hideStack;

Error.captureStackTrace(this, this.constructor);
}
}

module.exports = LoaderError;
89 changes: 44 additions & 45 deletions src/fs-cache.js → src/cache.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
/**
* Filesystem cache
* Filesystem Cache
*
* Given a file and a transform function, cache the result into files
* or retrieve the previously cached files if the given file is already known.
*
* @see https://github.com/babel/babel-loader/issues/34
* @see https://github.com/babel/babel-loader/pull/41
*/
const crypto = require("crypto");
const mkdirp = require("mkdirp");
const findCacheDir = require("find-cache-dir");
const fs = require("fs");
const os = require("os");
const path = require("path");
const zlib = require("zlib");
const crypto = require("crypto");
const mkdirp = require("mkdirp");
const findCacheDir = require("find-cache-dir");

let defaultCacheDirectory = null; // Lazily instantiated when needed
const transform = require("./transform");
// Lazily instantiated when needed
let cacheDirectory = null;

/**
* Read the contents from the compressed file.
Expand All @@ -25,13 +27,13 @@ let defaultCacheDirectory = null; // Lazily instantiated when needed
* @params {Function} callback
*/
const read = function(filename, callback) {
return fs.readFile(filename, function(err, data) {
return fs.readFile(filename, (err, data) => {
if (err) return callback(err);

return zlib.gunzip(data, function(err, content) {
return zlib.gunzip(data, (err, content) => {
if (err) return callback(err);

let result = {};
let result = Object.create(null);

try {
result = JSON.parse(content);
Expand All @@ -55,7 +57,7 @@ const read = function(filename, callback) {
const write = function(filename, result, callback) {
const content = JSON.stringify(result);

return zlib.gzip(content, function(err, data) {
return zlib.gzip(content, (err, data) => {
if (err) return callback(err);

return fs.writeFile(filename, data, callback);
Expand All @@ -72,11 +74,8 @@ const write = function(filename, result, callback) {
*/
const filename = function(source, identifier, options) {
const hash = crypto.createHash("SHA1");
const contents = JSON.stringify({
source: source,
options: options,
identifier: identifier,
});

const contents = JSON.stringify({ source, options, identifier });

hash.end(contents);

Expand All @@ -91,45 +90,45 @@ const filename = function(source, identifier, options) {
* @params {Function} callback
*/
const handleCache = function(directory, params, callback) {
const source = params.source;
const options = params.options || {};
const transform = params.transform;
const identifier = params.identifier;
const shouldFallback =
const { source, options = {}, cacheIdentifier } = params;

const fallback =
typeof params.directory !== "string" && directory !== os.tmpdir();

// Make sure the directory exists.
mkdirp(directory, function(err) {
mkdirp(directory, err => {
// Fallback to tmpdir if node_modules folder not writable
if (err)
return shouldFallback
if (err) {
return fallback
? handleCache(os.tmpdir(), params, callback)
: callback(err);
}

const file = path.join(directory, filename(source, identifier, options));
const file = path.join(
directory,
filename(source, cacheIdentifier, options),
);

return read(file, function(err, content) {
let result = {};
return read(file, (err, content) => {
// No errors mean that the file was previously cached
// we just need to return it
if (!err) return callback(null, content);

// Otherwise just transform the file
// return it to the user asap and write it in cache
try {
result = transform(source, options);
} catch (error) {
return callback(error);
}

return write(file, result, function(err) {
// Fallback to tmpdir if node_modules folder not writable
if (err)
return shouldFallback
? handleCache(os.tmpdir(), params, callback)
: callback(err);

callback(null, result);
return transform(source, options, (err, result) => {
if (err) return callback(err);

return write(file, result, err => {
// Fallback to tmpdir if node_modules folder not writable
if (err) {
return fallback
? handleCache(os.tmpdir(), params, callback)
: callback(err);
}

return callback(null, result);
});
});
});
});
Expand Down Expand Up @@ -172,14 +171,14 @@ const handleCache = function(directory, params, callback) {
module.exports = function(params, callback) {
let directory;

if (typeof params.directory === "string") {
directory = params.directory;
if (typeof params.cacheDirectory === "string") {
directory = params.cacheDirectory;
} else {
if (defaultCacheDirectory === null) {
defaultCacheDirectory =
findCacheDir({ name: "babel-loader" }) || os.tmpdir();
if (cacheDirectory === null) {
cacheDirectory = findCacheDir({ name: "babel-loader" }) || os.tmpdir();
}
directory = defaultCacheDirectory;

directory = cacheDirectory;
}

handleCache(directory, params, callback);
Expand Down
26 changes: 26 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const path = require("path");
const exists = require("./utils/exists");

const configs = [".babelrc", ".babelrc.js", "package.json"];

module.exports = function find(fs, start) {
for (let config of configs) {
config = path.join(start, config);

if (exists(fs, config)) {
if (
path.basename(config) !== "package.json" ||
typeof require(config).babel === "object"
) {
return config;
}
}
}

const up = path.dirname(start);

// Reached root
if (up !== start) {
return find(fs, up);
}
};
Loading