@web/dev-server-rollup
Advanced tools
Comparing version 0.1.2 to 0.1.3
# @web/dev-server-rollup | ||
## 0.1.3 | ||
### Patch Changes | ||
- f9dfcd3: improve rollup syntax error logging | ||
- Updated dependencies [8596276] | ||
- @web/dev-server-core@0.1.5 | ||
## 0.1.2 | ||
@@ -4,0 +12,0 @@ |
@@ -10,3 +10,5 @@ "use strict"; | ||
const whatwg_url_1 = __importDefault(require("whatwg-url")); | ||
const dev_server_core_1 = require("@web/dev-server-core"); | ||
const url_1 = require("url"); | ||
const chalk_1 = require("chalk"); | ||
const utils_1 = require("./utils"); | ||
@@ -16,3 +18,3 @@ const createRollupPluginContextAdapter_1 = require("./createRollupPluginContextAdapter"); | ||
const NULL_BYTE_PARAM = 'web-dev-server-rollup-null-byte'; | ||
const VIRTUAL_FILE_PREFIX = '/__web-dev-server__'; | ||
const VIRTUAL_FILE_PREFIX = '/__web-dev-server__/rollup'; | ||
function resolveFilePath(rootDir, path) { | ||
@@ -22,2 +24,17 @@ const fileUrl = new url_1.URL(`.${path}`, `${url_1.pathToFileURL(rootDir)}/`); | ||
} | ||
/** | ||
* Wraps rollup error in a custom error for web dev server. | ||
*/ | ||
function wrapRollupError(filePath, context, error) { | ||
var _a, _b; | ||
if (typeof error == null || typeof error !== 'object') { | ||
return error; | ||
} | ||
if (typeof ((_a = error === null || error === void 0 ? void 0 : error.loc) === null || _a === void 0 ? void 0 : _a.line) === 'number' && typeof ((_b = error === null || error === void 0 ? void 0 : error.loc) === null || _b === void 0 ? void 0 : _b.column) === 'number') { | ||
return new dev_server_core_1.PluginSyntaxError( | ||
// replace file path in error message since it will be reported be the dev server | ||
error.message.replace(new RegExp(`(\\s*in\\s*)?(${filePath})`), ''), filePath, context.body, error.loc.line, error.loc.column); | ||
} | ||
return error; | ||
} | ||
function rollupAdapter(rollupPlugin, rollupInputOptions = {}) { | ||
@@ -54,57 +71,57 @@ const transformedFiles = new Set(); | ||
const filePath = resolveFilePath(rootDir, requestedFile); | ||
const rollupPluginContext = createRollupPluginContextAdapter_1.createRollupPluginContextAdapter(rollupPluginContexts.pluginContext, wdsPlugin, config, fileWatcher, context); | ||
let resolvableImport = source; | ||
let importSuffix = ''; | ||
// we have to special case node-resolve because it doesn't support resolving | ||
// with hash/params at the moment | ||
if (rollupPlugin.name === 'node-resolve') { | ||
const [withoutHash, hash] = source.split('#'); | ||
const [importPath, params] = withoutHash.split('?'); | ||
importSuffix = `${params ? `?${params}` : ''}${hash ? `#${hash}` : ''}`; | ||
resolvableImport = importPath; | ||
} | ||
// if the import was already a fully resolved file path, it was probably injected by a plugin. | ||
// in that case use that instead of resolving it through a plugin hook. this puts the resolved file | ||
// path through the regular logic to turn it into a relative browser import | ||
// otherwise call the resolveID hook on the plugin | ||
const result = injectedFilePath | ||
? resolvableImport | ||
: await ((_a = rollupPlugin.resolveId) === null || _a === void 0 ? void 0 : _a.call(rollupPluginContext, resolvableImport, filePath)); | ||
let resolvedImportFilePath = undefined; | ||
if (typeof result === 'string') { | ||
resolvedImportFilePath = result; | ||
} | ||
else if (typeof result === 'object' && typeof (result === null || result === void 0 ? void 0 : result.id) === 'string') { | ||
resolvedImportFilePath = result.id; | ||
} | ||
if (!resolvedImportFilePath) { | ||
return undefined; | ||
} | ||
const hasNullByte = resolvedImportFilePath.includes('\0'); | ||
const withoutNullByte = hasNullByte | ||
? resolvedImportFilePath.replace(new RegExp('\0', 'g'), '') | ||
: resolvedImportFilePath; | ||
if (withoutNullByte.startsWith(rootDir)) { | ||
const resolveRelativeTo = path_1.default.extname(filePath) ? path_1.default.dirname(filePath) : filePath; | ||
const relativeImportFilePath = path_1.default.relative(resolveRelativeTo, withoutNullByte); | ||
const resolvedImportPath = `${utils_1.toBrowserPath(relativeImportFilePath)}`; | ||
const prefixedImportPath = resolvedImportPath.startsWith('/') || resolvedImportPath.startsWith('.') | ||
? `${resolvedImportPath}${importSuffix}` | ||
: `./${resolvedImportPath}${importSuffix}`; | ||
if (!hasNullByte) { | ||
return prefixedImportPath; | ||
try { | ||
const rollupPluginContext = createRollupPluginContextAdapter_1.createRollupPluginContextAdapter(rollupPluginContexts.pluginContext, wdsPlugin, config, fileWatcher, context); | ||
let resolvableImport = source; | ||
let importSuffix = ''; | ||
// we have to special case node-resolve because it doesn't support resolving | ||
// with hash/params at the moment | ||
if (rollupPlugin.name === 'node-resolve') { | ||
const [withoutHash, hash] = source.split('#'); | ||
const [importPath, params] = withoutHash.split('?'); | ||
importSuffix = `${params ? `?${params}` : ''}${hash ? `#${hash}` : ''}`; | ||
resolvableImport = importPath; | ||
} | ||
const suffix = `${NULL_BYTE_PARAM}=${encodeURIComponent(resolvedImportFilePath)}`; | ||
if (prefixedImportPath.includes('?')) { | ||
return `${prefixedImportPath}&${suffix}`; | ||
// if the import was already a fully resolved file path, it was probably injected by a plugin. | ||
// in that case use that instead of resolving it through a plugin hook. this puts the resolved file | ||
// path through the regular logic to turn it into a relative browser import | ||
// otherwise call the resolveID hook on the plugin | ||
const result = injectedFilePath | ||
? resolvableImport | ||
: await ((_a = rollupPlugin.resolveId) === null || _a === void 0 ? void 0 : _a.call(rollupPluginContext, resolvableImport, filePath)); | ||
let resolvedImportPath = undefined; | ||
if (typeof result === 'string') { | ||
resolvedImportPath = result; | ||
} | ||
return `${prefixedImportPath}?${suffix}`; | ||
else if (typeof result === 'object' && typeof (result === null || result === void 0 ? void 0 : result.id) === 'string') { | ||
resolvedImportPath = result.id; | ||
} | ||
if (!resolvedImportPath) { | ||
return undefined; | ||
} | ||
// if the resolved import includes a null byte (\0) there is some special logic | ||
// these often are not valid file paths, so the browser cannot request them. | ||
// we rewrite them to a special URL which we deconstruct later when we load the file | ||
if (resolvedImportPath.includes('\0')) { | ||
const filename = path_1.default.basename(resolvedImportPath.replace(/\0*/g, '').split('?')[0].split('#')[0]); | ||
const urlParam = encodeURIComponent(resolvedImportPath); | ||
return `${VIRTUAL_FILE_PREFIX}/${filename}?${NULL_BYTE_PARAM}=${urlParam}`; | ||
} | ||
// some plugins don't return a file path, so we just return it as is | ||
if (!utils_1.isAbsoluteFilePath(resolvedImportPath)) { | ||
return `${resolvedImportPath}`; | ||
} | ||
if (!resolvedImportPath.startsWith(rootDir)) { | ||
throw new dev_server_core_1.PluginError(chalk_1.red(`Resolved an import to ${chalk_1.yellow(resolvedImportPath)}`) + | ||
chalk_1.red('. This path is not reachable from the browser because') + | ||
chalk_1.red(` it is outside root directory ${chalk_1.yellow(rootDir)}`) + | ||
chalk_1.red(`. Configure the root directory using the ${chalk_1.yellow('--root-dir')} or ${chalk_1.yellow('rootDir')} option.`)); | ||
} | ||
const resolveRelativeTo = path_1.default.extname(filePath) ? path_1.default.dirname(filePath) : filePath; | ||
const relativeImportFilePath = path_1.default.relative(resolveRelativeTo, resolvedImportPath); | ||
const importBrowserPath = `${utils_1.toBrowserPath(relativeImportFilePath)}`; | ||
return `./${importBrowserPath}${importSuffix}`; | ||
} | ||
// if the resolved import includes a null byte (\0) there is some special logic | ||
// these often are not valid file paths, so the browser cannot request them. | ||
// we rewrite them to a special URL which we deconstruct later when we load the file | ||
if (resolvedImportFilePath.includes('\0')) { | ||
return `${VIRTUAL_FILE_PREFIX}/?${NULL_BYTE_PARAM}=${encodeURIComponent(resolvedImportFilePath)}`; | ||
catch (error) { | ||
throw wrapRollupError(filePath, context, error); | ||
} | ||
return `${resolvedImportFilePath}${importSuffix}`; | ||
}, | ||
@@ -117,3 +134,4 @@ async serve(context) { | ||
let filePath; | ||
if (context.URL.searchParams.has(NULL_BYTE_PARAM)) { | ||
if (context.path.startsWith(VIRTUAL_FILE_PREFIX) && | ||
context.URL.searchParams.has(NULL_BYTE_PARAM)) { | ||
// if this was a special URL constructed in resolveImport to handle null bytes, | ||
@@ -126,9 +144,14 @@ // the file path is stored in the search paramter | ||
} | ||
const rollupPluginContext = createRollupPluginContextAdapter_1.createRollupPluginContextAdapter(rollupPluginContexts.pluginContext, wdsPlugin, config, fileWatcher, context); | ||
const result = await ((_a = rollupPlugin.load) === null || _a === void 0 ? void 0 : _a.call(rollupPluginContext, filePath)); | ||
if (typeof result === 'string') { | ||
return { body: result, type: 'js' }; | ||
try { | ||
const rollupPluginContext = createRollupPluginContextAdapter_1.createRollupPluginContextAdapter(rollupPluginContexts.pluginContext, wdsPlugin, config, fileWatcher, context); | ||
const result = await ((_a = rollupPlugin.load) === null || _a === void 0 ? void 0 : _a.call(rollupPluginContext, filePath)); | ||
if (typeof result === 'string') { | ||
return { body: result, type: 'js' }; | ||
} | ||
if (typeof (result === null || result === void 0 ? void 0 : result.code) === 'string') { | ||
return { body: result.code, type: 'js' }; | ||
} | ||
} | ||
if (typeof (result === null || result === void 0 ? void 0 : result.code) === 'string') { | ||
return { body: result.code, type: 'js' }; | ||
catch (error) { | ||
throw wrapRollupError(filePath, context, error); | ||
} | ||
@@ -144,16 +167,21 @@ return undefined; | ||
const filePath = resolveFilePath(rootDir, context.path); | ||
const rollupPluginContext = createRollupPluginContextAdapter_1.createRollupPluginContextAdapter(rollupPluginContexts.transformPluginContext, wdsPlugin, config, fileWatcher, context); | ||
const result = await ((_a = rollupPlugin.transform) === null || _a === void 0 ? void 0 : _a.call(rollupPluginContext, context.body, filePath)); | ||
let transformedCode = undefined; | ||
if (typeof result === 'string') { | ||
transformedCode = result; | ||
try { | ||
const rollupPluginContext = createRollupPluginContextAdapter_1.createRollupPluginContextAdapter(rollupPluginContexts.transformPluginContext, wdsPlugin, config, fileWatcher, context); | ||
const result = await ((_a = rollupPlugin.transform) === null || _a === void 0 ? void 0 : _a.call(rollupPluginContext, context.body, filePath)); | ||
let transformedCode = undefined; | ||
if (typeof result === 'string') { | ||
transformedCode = result; | ||
} | ||
if (typeof result === 'object' && typeof (result === null || result === void 0 ? void 0 : result.code) === 'string') { | ||
transformedCode = result.code; | ||
} | ||
if (transformedCode) { | ||
transformedFiles.add(context.path); | ||
return transformedCode; | ||
} | ||
return; | ||
} | ||
if (typeof result === 'object' && typeof (result === null || result === void 0 ? void 0 : result.code) === 'string') { | ||
transformedCode = result.code; | ||
catch (error) { | ||
throw wrapRollupError(filePath, context, error); | ||
} | ||
if (transformedCode) { | ||
transformedFiles.add(context.path); | ||
return transformedCode; | ||
} | ||
return; | ||
} | ||
@@ -160,0 +188,0 @@ }, |
@@ -7,2 +7,3 @@ /** | ||
export declare function toBrowserPath(filePath: string): string; | ||
export declare function isAbsoluteFilePath(path: string): boolean; | ||
//# sourceMappingURL=utils.d.ts.map |
@@ -6,4 +6,5 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.toBrowserPath = void 0; | ||
exports.isAbsoluteFilePath = exports.toBrowserPath = void 0; | ||
const path_1 = __importDefault(require("path")); | ||
const REGEXP_ABSOLUTE = /^(?:\/|(?:[A-Za-z]:)?[\\|/])/; | ||
/** | ||
@@ -18,2 +19,6 @@ * Turns a file path into a path suitable for browsers, with a / as seperator. | ||
exports.toBrowserPath = toBrowserPath; | ||
function isAbsoluteFilePath(path) { | ||
return REGEXP_ABSOLUTE.test(path); | ||
} | ||
exports.isAbsoluteFilePath = isAbsoluteFilePath; | ||
//# sourceMappingURL=utils.js.map |
{ | ||
"name": "@web/dev-server-rollup", | ||
"version": "0.1.2", | ||
"version": "0.1.3", | ||
"publishConfig": { | ||
@@ -21,5 +21,8 @@ "access": "public" | ||
"scripts": { | ||
"test": "mocha \"test/**/*.test.ts\" --require ts-node/register --reporter progress", | ||
"test": "yarn test:node && yarn test:browser", | ||
"test:browser": "node ../test-runner/dist/test-runner.js test/browser/**/*.test.js --node-resolve", | ||
"test:browser:watch": "node ../test-runner/dist/test-runner.js test/browser/**/*.test.js --node-resolve --watch", | ||
"test:ci": "yarn test", | ||
"test:watch": "mocha \"test/**/*.test.ts\" --require ts-node/register --watch --watch-files src,test --reporter progress" | ||
"test:node": "mocha \"test/node/**/*.test.ts\" --require ts-node/register --reporter progress", | ||
"test:node:watch": "mocha \"test/node/**/*.test.ts\" --require ts-node/register --watch --watch-files src,test --reporter progress" | ||
}, | ||
@@ -42,3 +45,4 @@ "files": [ | ||
"dependencies": { | ||
"@web/dev-server-core": "^0.1.1", | ||
"@web/dev-server-core": "^0.1.5", | ||
"chalk": "^4.1.0", | ||
"rollup": "^2.20.0", | ||
@@ -48,3 +52,6 @@ "whatwg-url": "^8.1.0" | ||
"devDependencies": { | ||
"@babel/plugin-transform-template-literals": "^7.10.4", | ||
"@rollup/plugin-alias": "^3.1.1", | ||
"@rollup/plugin-babel": "^5.0.4", | ||
"@rollup/plugin-commonjs": "^13.0.0", | ||
"@rollup/plugin-image": "^2.0.5", | ||
@@ -54,4 +61,10 @@ "@rollup/plugin-inject": "^4.0.2", | ||
"@rollup/plugin-node-resolve": "^8.1.0", | ||
"@rollup/plugin-replace": "^2.3.3" | ||
"@rollup/plugin-replace": "^2.3.3", | ||
"@rollup/plugin-url": "^5.0.1", | ||
"@types/node-fetch": "^2.5.7", | ||
"chai": "^4.2.0", | ||
"node-fetch": "^2.6.0", | ||
"rollup-plugin-postcss": "^3.1.2", | ||
"sinon": "^9.0.2" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
37148
377
4
15
1
+ Addedchalk@^4.1.0
+ Addedansi-styles@4.3.0(transitive)
+ Addedchalk@4.1.2(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcolor-name@1.1.4(transitive)
+ Addedhas-flag@4.0.0(transitive)
+ Addedsupports-color@7.2.0(transitive)
Updated@web/dev-server-core@^0.1.5