Skip to content

Commit

Permalink
Revert #55, #60
Browse files Browse the repository at this point in the history
* Revert "Fixup and document cache attachment (#58)"

This reverts commit d654e70.

* Revert "use webpack public path in asset emission (#55)"

This reverts commit e5cff63.
  • Loading branch information
guybedford authored Jul 2, 2019
1 parent c45940a commit ccbb342
Show file tree
Hide file tree
Showing 129 changed files with 244 additions and 368 deletions.
41 changes: 0 additions & 41 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,47 +62,6 @@ Any `.node` files included will also support binary relocation.

Assets will be emitted using `emitAsset`, with their references updated in the code by the loader to the new output location.

### Asset Permissions and Symlinks

Asset symlinks and permissions are maintained in the loader, but aren't passed to Webpack as `emit` doesn't support these.

This information can be obtained from the loader through the API calls `getAssetPermissions()` and `getSymlinks()`:

```js
const relocateLoader = require('webpack-asset-relocator-loader');

webpack({...}).run((err, stats) => {
const assetPermissions = relocateLoader.getAssetPermissions();
const symlinks = relocateLoader.getSymlinks();
});
```

They will always contain the most recent build state.

### Caching

When using Webpack 5 caching, asset permissions need to be maintained through their own cache, and the public path needs to be injected into the build.

To ensure these cases work out, make sure to run `initAssetCache` in the build, with the `options.outputAssetBase` argument:

```js
const relocateLoader = require('webpack-asset-relocator-loader');

webpack({
// ...

plugins: [
{
apply(compiler) {
compiler.hooks.compilation.tap("webpack-asset-relocator-loader", compilation => {
relocateLoader.initAssetCache(compilation, outputAssetBase);
});
}
}
]
});
```

## How it Works

### Asset Relocation
Expand Down
65 changes: 25 additions & 40 deletions src/asset-relocator.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,22 @@ function getEntryIds (compilation) {
}
}

function assetBase (outputAssetBase) {
function assetBase (options) {
const outputAssetBase = options && options.outputAssetBase;
if (!outputAssetBase)
return '';
if (outputAssetBase.endsWith('/') || outputAssetBase.endsWith('\\'))
return outputAssetBase;
return outputAssetBase + '/';
}

function relAssetPath (context, options) {
const isChunk = context._module.reasons && context._module.reasons.every(reason => reason.module);
const filename = isChunk && context._compilation.outputOptions.chunkFilename || context._compilation.outputOptions.filename;
const backtrackDepth = filename.split(/[\\/]/).length - 1;
return '../'.repeat(backtrackDepth) + assetBase(options);
}

const staticProcess = {
cwd: () => {
return cwd;
Expand Down Expand Up @@ -279,58 +287,36 @@ function generateWildcardRequire(dir, wildcardPath, wildcardParam, wildcardBlock
return `__ncc_wildcard$${wildcardBlockIndex}(${wildcardParam})`;
}

const hooked = new WeakSet();
function injectPathHook (compilation, outputAssetBase) {
const { mainTemplate } = compilation;
if (!hooked.has(mainTemplate)) {
hooked.add(mainTemplate);

mainTemplate.hooks.requireExtensions.tap("asset-relocator-loader", (source, chunk) => {
let relBase = '';
if (chunk.name) {
relBase = path.relative(path.dirname(chunk.name), '.').replace(/\\/g, '/');
if (relBase.length)
relBase = '/' + relBase;
}
return `${source}\n${mainTemplate.requireFn}.ab = __dirname + ${JSON.stringify(relBase + '/' + assetBase(outputAssetBase))};`;
});
}
}

module.exports = async function (content, map) {
if (this.cacheable)
this.cacheable();
this.async();
const id = this.resourcePath;
const dir = path.dirname(id);

// injection to set __webpack_require__.ab
const options = getOptions(this);

injectPathHook(this._compilation, options.outputAssetBase);

if (id.endsWith('.node')) {
const options = getOptions(this);
const assetState = getAssetState(options, this._compilation);
const pkgBase = getPackageBase(this.resourcePath) || dir;
await sharedlibEmit(pkgBase, assetState, assetBase(options.outputAssetBase), this.emitFile);
await sharedlibEmit(pkgBase, assetState, assetBase(options), this.emitFile);

const name = getUniqueAssetName(id.substr(pkgBase.length + 1), id, assetState.assetNames);

const permissions = await new Promise((resolve, reject) =>
stat(id, (err, stats) => err ? reject(err) : resolve(stats.mode))
);
assetState.assetPermissions[name] = permissions;
this.emitFile(assetBase(options.outputAssetBase) + name, content);
this.emitFile(assetBase(options) + name, content);

this.callback(null, 'module.exports = __non_webpack_require__(__webpack_require__.ab + ' + JSON.stringify(name) + ')');
this.callback(null, 'module.exports = __non_webpack_require__("./' + relAssetPath(this, options) + JSON.stringify(name).slice(1, -1) + '")');
return;
}

if (id.endsWith('.json'))
return this.callback(null, code, map);

let code = content.toString();


const options = getOptions(this);
if (typeof options.production === 'boolean' && staticProcess.env.NODE_ENV === UNKNOWN) {
staticProcess.env.NODE_ENV = options.production ? 'production' : 'dev';
}
Expand All @@ -357,7 +343,7 @@ module.exports = async function (content, map) {
outName = assetPath.substr(pkgBase.length).replace(/\\/g, '/');
// If the asset is a ".node" binary, then glob for possible shared
// libraries that should also be included
const nextPromise = sharedlibEmit(pkgBase, assetState, assetBase(options.outputAssetBase), this.emitFile);
const nextPromise = sharedlibEmit(pkgBase, assetState, assetBase(options), this.emitFile);
assetEmissionPromises = assetEmissionPromises.then(() => {
return nextPromise;
});
Expand All @@ -384,14 +370,14 @@ module.exports = async function (content, map) {
readlink(assetPath, (err, path) => err ? reject(err) : resolve(path));
});
const baseDir = path.dirname(assetPath);
assetState.assetSymlinks[assetBase(options.outputAssetBase) + name] = path.relative(baseDir, path.resolve(baseDir, symlink));
assetState.assetSymlinks[assetBase(options) + name] = path.relative(baseDir, path.resolve(baseDir, symlink));
}
else {
assetState.assetPermissions[assetBase(options.outputAssetBase) + name] = stats.mode;
this.emitFile(assetBase(options.outputAssetBase) + name, source);
assetState.assetPermissions[assetBase(options) + name] = stats.mode;
this.emitFile(assetBase(options) + name, source);
}
});
return "__webpack_require__.ab + " + JSON.stringify(name);
return "__dirname + '/" + relAssetPath(this, options) + JSON.stringify(name).slice(1, -1) + "'";
};
const emitAssetDirectory = (wildcardPath, wildcards) => {
const wildcardIndex = wildcardPath.indexOf(WILDCARD);
Expand Down Expand Up @@ -432,11 +418,11 @@ module.exports = async function (content, map) {
readlink(file, (err, path) => err ? reject(err) : resolve(path));
});
const baseDir = path.dirname(file);
assetState.assetSymlinks[assetBase(options.outputAssetBase) + name + file.substr(assetDirPath.length)] = path.relative(baseDir, path.resolve(baseDir, symlink)).replace(/\\/g, '/');
assetState.assetSymlinks[assetBase(options) + name + file.substr(assetDirPath.length)] = path.relative(baseDir, path.resolve(baseDir, symlink)).replace(/\\/g, '/');
}
else {
assetState.assetPermissions[assetBase(options.outputAssetBase) + name + file.substr(assetDirPath.length)] = stats.mode;
this.emitFile(assetBase(options.outputAssetBase) + name + file.substr(assetDirPath.length), source);
assetState.assetPermissions[assetBase(options) + name + file.substr(assetDirPath.length)] = stats.mode;
this.emitFile(assetBase(options) + name + file.substr(assetDirPath.length), source);
}
}));
});
Expand Down Expand Up @@ -466,7 +452,7 @@ module.exports = async function (content, map) {
assetExpressions += " + \'" + JSON.stringify(curPattern).slice(1, -1) + "'";
}
}
return "__webpack_require__.ab + " + JSON.stringify(name + firstPrefix) + assetExpressions;
return "__dirname + '/" + relAssetPath(this, options) + JSON.stringify(name + firstPrefix).slice(1, -1) + "'" + assetExpressions;
};

let assetEmissionPromises = Promise.resolve();
Expand Down Expand Up @@ -1217,8 +1203,7 @@ module.exports.getSymlinks = function() {
return lastState.assetSymlinks;
};

module.exports.initAssetCache = module.exports.initAssetPermissionsCache = function (compilation, outputAssetBase) {
injectPathHook(compilation, outputAssetBase);
module.exports.initAssetPermissionsCache = function (compilation) {
const entryIds = getEntryIds(compilation);
if (!entryIds)
return;
Expand Down
6 changes: 3 additions & 3 deletions test/project-chunking/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ const fs = require('fs');
expect(output.length).toBe(18);

// check relative asset references worked out
expect(fs.readFileSync(__dirname + "/dist/modules/main.js").toString()).toContain(`ab+"asset`);
expect(fs.readFileSync(__dirname + "/dist/modules/chunk.js").toString()).toContain(`ab+"asset`);
expect(fs.readFileSync(__dirname + "/dist/modules/chunks/2.js").toString()).toContain(`ab+"asset`);
expect(fs.readFileSync(__dirname + "/dist/modules/main.js").toString()).toContain(`"/../asset`);
expect(fs.readFileSync(__dirname + "/dist/modules/chunk.js").toString()).toContain(`"/../asset`);
expect(fs.readFileSync(__dirname + "/dist/modules/chunks/2.js").toString()).toContain(`"/../../asset`);
1 change: 0 additions & 1 deletion test/unit/amd-disable/output-coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ module.exports =
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/
/******/ // Load entry module and return exports
Expand Down
1 change: 0 additions & 1 deletion test/unit/amd-disable/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ module.exports =
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/
/******/ // Load entry module and return exports
Expand Down
8 changes: 4 additions & 4 deletions test/unit/array-emission/output-coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ module.exports =
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/
/******/ // Load entry module and return exports
Expand All @@ -91,15 +90,16 @@ module.exports =
/***/ (function(module, exports, __webpack_require__) {

"use strict";

/* WEBPACK VAR INJECTION */(function(__dirname) {

const fs = __webpack_require__(1);

const REPORT_JAVASCRIPT = [
fs.readFileSync(__webpack_require__.ab + "util.js", 'utf8'),
fs.readFileSync(__webpack_require__.ab + "dom.js", 'utf8'),
fs.readFileSync(__dirname + '/util.js', 'utf8'),
fs.readFileSync(__dirname + '/dom.js', 'utf8'),
].join(';\n');

/* WEBPACK VAR INJECTION */}.call(this, "/"))

/***/ }),
/* 1 */
Expand Down
8 changes: 4 additions & 4 deletions test/unit/array-emission/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ module.exports =
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/
/******/ // Load entry module and return exports
Expand All @@ -91,15 +90,16 @@ module.exports =
/***/ (function(module, exports, __webpack_require__) {

"use strict";

/* WEBPACK VAR INJECTION */(function(__dirname) {

const fs = __webpack_require__(1);

const REPORT_JAVASCRIPT = [
fs.readFileSync(__webpack_require__.ab + "util.js", 'utf8'),
fs.readFileSync(__webpack_require__.ab + "dom.js", 'utf8'),
fs.readFileSync(__dirname + '/util.js', 'utf8'),
fs.readFileSync(__dirname + '/dom.js', 'utf8'),
].join(';\n');

/* WEBPACK VAR INJECTION */}.call(this, "/"))

/***/ }),
/* 1 */
Expand Down
1 change: 0 additions & 1 deletion test/unit/array-holes/output-coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ module.exports =
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/
/******/ // Load entry module and return exports
Expand Down
1 change: 0 additions & 1 deletion test/unit/array-holes/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ module.exports =
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/
/******/ // Load entry module and return exports
Expand Down
6 changes: 3 additions & 3 deletions test/unit/asset-conditional/output-coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ module.exports =
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/
/******/ // Load entry module and return exports
Expand All @@ -90,8 +89,9 @@ module.exports =
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

const path = __webpack_require__(1);
let moduleJsPath = isHarmony ? __webpack_require__.ab + "asset1.txt" : __webpack_require__.ab + "asset2.txt";
/* WEBPACK VAR INJECTION */(function(__dirname) {const path = __webpack_require__(1);
let moduleJsPath = isHarmony ? __dirname + '/asset1.txt' : __dirname + '/asset2.txt';
/* WEBPACK VAR INJECTION */}.call(this, "/"))

/***/ }),
/* 1 */
Expand Down
6 changes: 3 additions & 3 deletions test/unit/asset-conditional/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ module.exports =
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/
/******/ // Load entry module and return exports
Expand All @@ -90,8 +89,9 @@ module.exports =
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

const path = __webpack_require__(1);
let moduleJsPath = isHarmony ? __webpack_require__.ab + "asset1.txt" : __webpack_require__.ab + "asset2.txt";
/* WEBPACK VAR INJECTION */(function(__dirname) {const path = __webpack_require__(1);
let moduleJsPath = isHarmony ? __dirname + '/asset1.txt' : __dirname + '/asset2.txt';
/* WEBPACK VAR INJECTION */}.call(this, "/"))

/***/ }),
/* 1 */
Expand Down
6 changes: 3 additions & 3 deletions test/unit/asset-fs-existing-asset-name/output-coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ module.exports =
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/
/******/ // Load entry module and return exports
Expand All @@ -90,9 +89,10 @@ module.exports =
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

const fs = __webpack_require__(1);
console.log(fs.readFileSync(__webpack_require__.ab + "existing1.txt"));
/* WEBPACK VAR INJECTION */(function(__dirname) {const fs = __webpack_require__(1);
console.log(fs.readFileSync(__dirname + '/existing1.txt'));

/* WEBPACK VAR INJECTION */}.call(this, "/"))

/***/ }),
/* 1 */
Expand Down
6 changes: 3 additions & 3 deletions test/unit/asset-fs-existing-asset-name/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ module.exports =
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/
/******/ // Load entry module and return exports
Expand All @@ -90,9 +89,10 @@ module.exports =
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

const fs = __webpack_require__(1);
console.log(fs.readFileSync(__webpack_require__.ab + "existing1.txt"));
/* WEBPACK VAR INJECTION */(function(__dirname) {const fs = __webpack_require__(1);
console.log(fs.readFileSync(__dirname + '/existing1.txt'));

/* WEBPACK VAR INJECTION */}.call(this, "/"))

/***/ }),
/* 1 */
Expand Down
Loading

0 comments on commit ccbb342

Please sign in to comment.