Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

Commit

Permalink
feat: Major HMR improvements
Browse files Browse the repository at this point in the history
* Supports loading missing files into memory respecting source maps
* Supports vendor reload

Related: #1483
  • Loading branch information
Ivan Orlov authored and unknown committed Feb 11, 2019
1 parent b476d49 commit 61c3a81
Show file tree
Hide file tree
Showing 21 changed files with 457 additions and 160 deletions.
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ _current_test
.fusebox
bin
dist
modules
package.json
package-lock.json
3 changes: 3 additions & 0 deletions modules/fuse-box-loader-api/fusebox.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@ var FuseBox = (function () {
_loop_1(k);
}
};
FuseBox.consume = function (contents) {
new Function(contents)(true);
};
FuseBox.dynamic = function (path, str, opts) {
this.pkg((opts && opts.pkg) || "default", {}, function (___scope___) {
___scope___.file(path, function (exports, require, module, __filename, __dirname) {
Expand Down
2 changes: 1 addition & 1 deletion modules/fuse-box-loader-api/fusebox.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"bowser": "^2.0.0-beta.3",
"chokidar": "^1.6.1",
"clean-css": "^4.1.9",
"convert-source-map": "^1.6.0",
"escodegen": "^1.8.1",
"express": "^4.14.0",
"fliplog": "^0.3.13",
Expand All @@ -48,6 +49,7 @@
"inquirer": "^3.0.6",
"lego-api": "^1.0.7",
"mustache": "^2.3.0",
"offset-sourcemap-lines": "^1.0.1",
"postcss": "^6.0.1",
"pretty-time": "^0.2.0",
"prettysize": "0.0.3",
Expand All @@ -56,8 +58,8 @@
"request": "^2.79.0",
"shorthash": "0.0.2",
"source-map": "^0.7.1",
"stream-browserify": "^2.0.1",
"sourcemap-blender": "1.0.5",
"stream-browserify": "^2.0.1",
"tslib": "^1.8.0",
"watch": "^1.0.1",
"ws": "^1.1.1"
Expand Down Expand Up @@ -151,6 +153,7 @@
"format": "prettier --list-different \"**/*.{js,json,md,ts,yml}\"",
"format:fix": "prettier --write \"**/*.{js,json,md,ts,yml}\"",
"start": "gulp watch",
"dev": "rm -rf ./.fusebox; rm -rf ./.dev; gulp dev",
"test": "node test.js"
},
"typings": "index.d.ts",
Expand Down
9 changes: 3 additions & 6 deletions src/BundleSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export class BundleSource {
}

public annotate(comment: string) {
//this.collectionSource.add(null, comment);
this.collectionSource.add(null, comment);
}
/**
*
Expand All @@ -105,13 +105,12 @@ export class BundleSource {
conflicting[name] = version;
});
}
this.annotate(`/* fuse:start-collection "${collection.name}"*/`);

this.collectionSource.add(
null,
`FuseBox.pkg("${collection.name}", ${JSON.stringify(conflicting)}, function(___scope___){`,
);

this.annotate(`/* fuse:start-collection "${collection.name}"*/`);
}

/**
Expand Down Expand Up @@ -176,13 +175,11 @@ export class BundleSource {
${file.headerContent ? file.headerContent.join("\n") : ""}`,
);

this.annotate(`/* fuse:start-file "${file.info.fuseBoxPath}"*/`);
this.collectionSource.add(
null,
file.alternativeContent !== undefined ? file.alternativeContent : file.contents,
file.sourceMap,
);
this.annotate(`/* fuse:end-file "${file.info.fuseBoxPath}"*/`);

this.collectionSource.add(null, "});");
}
Expand Down Expand Up @@ -272,7 +269,7 @@ ${file.headerContent ? file.headerContent.join("\n") : ""}`,
// cache busting should not be used if the target is a server, as it will interfere with local filesystem resolution
this.concat.add(null, `//# sourceMappingURL=${sourceName}.js.map`);
} else {
this.concat.add(null, `//# sourceMappingURL=${sourceName}.js.map?tm=${this.context.cacheBustPreffix}`);
this.concat.add(null, `//# sourceMappingURL=${sourceName}.js.map`);
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/ModuleCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ export class ModuleCache {
return encodeURIComponent(str);
}

public findInMemoryCache(target: string) {
console.log(MEMORY_CACHE);
}

/**
*
*
Expand Down
23 changes: 10 additions & 13 deletions src/core/Bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,9 @@ export class Bundle {
* This will allow use to enable HMR on any bundle within current producer
*/
this.producer.sharedEvents.on("SocketServerReady", (server: SocketServer) => {
this.fuse.context.sourceChangedEmitter.on(info => {
this.fuse.context.hmrEmitter.on(req => {
if (this.fuse.context.isFirstTime() === false) {
this.fuse.context.log.echo(`Source changed for ${info.path}`);
server.send("source-changed", info);
server.emit(req.event, req.data);
}
});

Expand All @@ -112,23 +111,21 @@ export class Bundle {
});

this.errorEmitter.on(message => {
server.send("bundle-error", {
bundleName: this.name,
message,
this.context.hmrEmitter.emit({
event: "bundle-error",
data: {
bundleName: this.name,
message,
},
});
});

this.clearErrorEmitter.on(() => {
server.send(type, getData());
server.emit(type, getData());
});

server.server.on("connection", client => {
client.send(
JSON.stringify({
type,
data: getData(),
}),
);
this.context.hmrEmitter.emit({ event: type, data: getData() });
});
}
});
Expand Down
53 changes: 49 additions & 4 deletions src/core/File.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
import { ModuleCollection } from "./ModuleCollection";
import * as convertSourceMap from "convert-source-map";
import * as fs from "fs";
import * as offsetLines from "offset-sourcemap-lines";
import * as path from "path";
import { each, utils } from "realm-utils";
import { FileAnalysis, TraversalPlugin } from "../analysis/FileAnalysis";
import { WorkFlowContext, Plugin } from "./WorkflowContext";
import { IPathInformation, IPackageInformation } from "./PathMaster";
import {
ensureFuseBoxPath,
fastHash,
isStylesheetExtension,
joinFuseBoxPath,
readFuseBoxModule,
Concat,
} from "../Utils";
import { ModuleCollection } from "./ModuleCollection";
import { IPackageInformation, IPathInformation } from "./PathMaster";
import { SourceMapGenerator } from "./SourceMapGenerator";
import { utils, each } from "realm-utils";
import * as fs from "fs";
Expand Down Expand Up @@ -54,6 +66,8 @@ export class File {
public cached = false;

public devLibsRequired;

public resolvedDependencies: Array<File>;
/**
*
*
Expand Down Expand Up @@ -154,6 +168,7 @@ export class File {
* @memberOf File
*/
constructor(public context: WorkFlowContext, public info: IPathInformation) {
this.resolvedDependencies = [];
if (info.params) {
this.params = info.params;
}
Expand Down Expand Up @@ -656,6 +671,35 @@ export class File {
public getCorrectSourceMapPath() {
return this.context.sourceMapsRoot + "/" + this.relativePath;
}

public getHMRContent() {
const concat = new Concat(true, "", "\n");
const packageName = this.collection.name;
const source = this.alternativeContent ? this.alternativeContent : this.contents;
if (source) {
concat.add(null, `FuseBox.pkg("${packageName}", {}, function(___scope___){`);
concat.add(
null,
`___scope___.file("${this.info.fuseBoxPath}", function(exports, require, module, __filename, __dirname){`,
);
if (this.headerContent) {
concat.add(null, this.headerContent.join("\n"));
}
concat.add(this.getSourceMapPath(), source, this.sourceMap);
concat.add(null, "}); });");
let content = concat.content.toString();

if (this.sourceMap && concat.sourceMap) {
let json = JSON.parse(concat.sourceMap);
// since new Function wrapoer adds extra 2 lines we need to shift sourcemaps
json = offsetLines(json, 2);
const sm = convertSourceMap.fromObject(json).toComment();
content += "\n" + sm;
}
return content;
}
}

/**
*
*
Expand Down Expand Up @@ -690,7 +734,8 @@ export class File {
result.outputText = result.outputText
.replace(
`//# sourceMappingURL=${this.info.fuseBoxPath}.map`,
`//# sourceMappingURL=${this.context.bundle.name}.js.map?tm=${this.context.cacheBustPreffix}`,
"",
//`//# sourceMappingURL=${this.context.bundle.name}.js.map?tm=${this.context.cacheBustPreffix}`,
)
.replace("//# sourceMappingURL=module.js.map", "");
if (this.dynamicImportsReplaced) {
Expand Down
5 changes: 2 additions & 3 deletions src/core/FuseBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,8 @@ export class FuseBox {

const self = this;
return bundleCollection.collectBundle(bundleData).then(module => {
if (this.context.emitHMRDependencies) {
this.context.emitter.emit("bundle-collected");
}
this.context.emitter.emit("bundle-collected");

this.context.log.bundleStart(this.context.bundle.name);
return chain(
class extends Chainable {
Expand Down
10 changes: 7 additions & 3 deletions src/core/ModuleCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,14 +394,18 @@ export class ModuleCollection {

// Process file dependencies recursively

return each(file.analysis.dependencies, name => {
const newFile = new File(this.context, this.pm.resolve(name, file.info.absDir, fileLimitPath, file));
const resolvedFiles = await each(file.analysis.dependencies, async name => {
const resolvedInfo = this.pm.resolve(name, file.info.absDir, fileLimitPath, file);
const newFile = new File(this.context, resolvedInfo);
file.resolvedDependencies.push(newFile);
newFile.resolveDepsOnly = file.resolveDepsOnly;
if (this.context.emitHMRDependencies && file.belongsToProject()) {
this.context.registerDependant(newFile, file);
}
return this.resolve(newFile, shouldIgnoreDeps);
await this.resolve(newFile, shouldIgnoreDeps);
});

return resolvedFiles;
}
}
}
Loading

0 comments on commit 61c3a81

Please sign in to comment.