Skip to content

Commit

Permalink
feat(rust): add output.sourceMapFilename api
Browse files Browse the repository at this point in the history
  • Loading branch information
lippzhang committed May 6, 2023
1 parent eaa1d60 commit 28156f6
Show file tree
Hide file tree
Showing 21 changed files with 637 additions and 531 deletions.
1,041 changes: 521 additions & 520 deletions crates/node_binding/binding.d.ts

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions crates/rspack_binding_options/src/options/raw_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ pub struct RawOutputOptions {
pub chunk_loading: Option<String>,
pub enabled_chunk_loading_types: Option<Vec<String>>,
pub trusted_types: Option<RawTrustedTypes>,
pub source_map_filename: String,
}

impl RawOptionsApply for RawOutputOptions {
Expand Down Expand Up @@ -186,6 +187,7 @@ impl RawOptionsApply for RawOutputOptions {
iife: self.iife,
module: self.module,
trusted_types: self.trusted_types.map(Into::into),
source_map_filename: self.source_map_filename.into(),
})
}
}
Expand Down
26 changes: 26 additions & 0 deletions crates/rspack_core/src/options/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub struct OutputOptions {
pub iife: bool,
pub module: bool,
pub trusted_types: Option<TrustedTypes>,
pub source_map_filename: Filename,
}

#[derive(Debug)]
Expand Down Expand Up @@ -79,6 +80,7 @@ impl std::fmt::Display for CrossOriginLoading {
}
}

pub const FILE_PLACEHOLDER: &str = "[file]";
pub const NAME_PLACEHOLDER: &str = "[name]";
pub const PATH_PLACEHOLDER: &str = "[path]";
pub const EXT_PLACEHOLDER: &str = "[ext]";
Expand All @@ -93,6 +95,7 @@ pub const QUERY_PLACEHOLDER: &str = "[query]";

#[derive(Debug, Default)]
pub struct FilenameRenderOptions {
pub file: Option<String>,
pub name: Option<String>,
pub path: Option<String>,
pub extension: Option<String>,
Expand Down Expand Up @@ -142,9 +145,32 @@ impl Filename {
..Default::default()
})
}
pub fn render_with_chunk_and_file(
&self,
chunk: &Chunk,
file: &str,
extension: &str,
source_type: &SourceType,
) -> String {
let hash = Some(chunk.get_render_hash());
self.render(FilenameRenderOptions {
// See https://github.com/webpack/webpack/blob/4b4ca3bb53f36a5b8fc6bc1bd976ed7af161bd80/lib/TemplatedPathPlugin.js#L214
file: Some(file.to_owned()),
name: chunk.name_for_filename_template(),
extension: Some(extension.to_owned()),
id: chunk.id.clone(),
contenthash: chunk.content_hash.get(source_type).cloned(),
chunkhash: hash.clone(),
hash,
..Default::default()
})
}

pub fn render(&self, options: FilenameRenderOptions) -> String {
let mut filename = self.template.clone();
if let Some(file) = options.file {
filename = filename.replace(FILE_PLACEHOLDER, &file);
}
if let Some(name) = options.name {
filename = filename.replace(NAME_PLACEHOLDER, &name);
}
Expand Down
1 change: 1 addition & 0 deletions crates/rspack_loader_sass/tests/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ async fn loader_test(actual: impl AsRef<Path>, expected: impl AsRef<Path>) {
iife: true,
module: false,
trusted_types: None,
source_map_filename: rspack_core::Filename::from_str("").expect("TODO:"),
},
target: rspack_core::Target::new(&vec![String::from("web")]).expect("TODO:"),
resolve: rspack_core::Resolve::default(),
Expand Down
2 changes: 2 additions & 0 deletions crates/rspack_plugin_asset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ impl ParserAndGenerator for AssetParserAndGenerator {
chunkhash: Some(hash.clone()),
hash: Some(hash),
query: Some("".to_string()),
..Default::default()
});

self
Expand Down Expand Up @@ -526,6 +527,7 @@ impl Plugin for AssetPlugin {
chunkhash,
hash,
query: Some("".to_string()),
..Default::default()
})
}),
PathData {
Expand Down
1 change: 1 addition & 0 deletions crates/rspack_plugin_copy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ impl CopyPlugin {
chunkhash: None,
hash: Some(content_hash.to_string()),
query: None,
..Default::default()
},
);

Expand Down
34 changes: 29 additions & 5 deletions crates/rspack_plugin_devtool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rspack_core::{
rspack_sources::{BoxSource, ConcatSource, MapOptions, RawSource, Source, SourceExt, SourceMap},
AssetInfo, Compilation, CompilationAsset, JsChunkHashArgs, Plugin, PluginContext,
PluginJsChunkHashHookOutput, PluginProcessAssetsOutput, PluginRenderModuleContentOutput,
ProcessAssetsArgs, RenderModuleContentArgs,
ProcessAssetsArgs, RenderModuleContentArgs, SourceType,
};
use rspack_error::{internal_error, Result};
use rspack_util::swc::normalize_custom_filename;
Expand Down Expand Up @@ -64,7 +64,6 @@ impl Plugin for DevtoolPlugin {
fn name(&self) -> &'static str {
"devtool"
}

fn render_module_content(
&self,
_ctx: PluginContext,
Expand Down Expand Up @@ -137,9 +136,10 @@ impl Plugin for DevtoolPlugin {
})
.collect::<Result<_>>()?;
for (filename, map_buffer) in maps {
let is_css = IS_CSS_FILE.is_match(&filename);
let current_source_mapping_url_comment =
self.source_mapping_url_comment.as_ref().map(|comment| {
if IS_CSS_FILE.is_match(&filename) {
if is_css {
format!("\n/*{comment}*/")
} else {
format!("\n//{comment}")
Expand All @@ -153,7 +153,7 @@ impl Plugin for DevtoolPlugin {
.compilation
.assets_mut()
.remove(&filename)
.expect("TODO:");
.unwrap_or_else(|| panic!("TODO:"));
asset.source = Some(
ConcatSource::new([
asset.source.expect("source should never be `None` here, because `maps` is collected by asset with `Some(source)`"),
Expand All @@ -167,7 +167,31 @@ impl Plugin for DevtoolPlugin {
);
args.compilation.emit_asset(filename, asset);
} else {
let source_map_filename = filename.clone() + ".map";
let mut source_map_filename = filename.to_owned() + ".map";
// https://webpack.docschina.org/configuration/output/#outputsourcemapfilename
if args.compilation.options.devtool.source_map() {
let source_map_filename_config = &args.compilation.options.output.source_map_filename;
for chunk in args.compilation.chunk_by_ukey.values() {
for file in &chunk.files {
if *file.to_string() == filename {
let extension = if is_css { ".css" } else { ".js" };
let source_type = if is_css {
&SourceType::Css
} else {
&SourceType::JavaScript
};
source_map_filename = source_map_filename_config.render_with_chunk_and_file(
chunk,
&filename,
extension,
source_type,
);
break;
}
}
}
}

if let Some(current_source_mapping_url_comment) = current_source_mapping_url_comment {
let source_map_url = if let Some(public_path) = &self.public_path {
format!("{public_path}{source_map_filename}")
Expand Down
1 change: 1 addition & 0 deletions crates/rspack_plugin_html/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ impl Plugin for HtmlPlugin {
chunkhash: Some(hash.clone()),
hash: Some(hash),
query: Some("".to_string()),
..Default::default()
});
compilation.emit_asset(
html_file_name,
Expand Down
4 changes: 4 additions & 0 deletions crates/rspack_testing/src/test_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ pub struct Output {
pub css_filename: String,
#[serde(default = "default_chunk_filename")]
pub css_chunk_filename: String,
#[serde(default = "default_chunk_filename")]
pub source_map_filename: String,
}

#[derive(Debug, JsonSchema, Deserialize)]
Expand Down Expand Up @@ -402,6 +404,8 @@ impl TestConfig {
iife: true,
module: false,
trusted_types: None,
source_map_filename: c::Filename::from_str(&self.output.source_map_filename)
.expect("Should exist"),
},
mode: c::Mode::from(self.mode),
target: c::Target::new(&self.target).expect("Can't construct target"),
Expand Down
4 changes: 4 additions & 0 deletions crates/rspack_testing/test.config.scheme.json
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,10 @@
"default": "[name][ext]",
"type": "string"
},
"source_map_filename": {
"default": "[name][ext]",
"type": "string"
},
"publicPath": {
"default": "auto",
"type": "string"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,4 @@
"sass-embedded-win32-x64": "1.58.3"
},
"packageManager": "pnpm@7.32.0"
}
}
3 changes: 2 additions & 1 deletion packages/rspack/src/config/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ function getRawOutput(output: OutputNormalized): RawOptions["output"] {
enabledWasmLoadingTypes: output.enabledWasmLoadingTypes!,
enabledChunkLoadingTypes: output.enabledChunkLoadingTypes!,
webassemblyModuleFilename: output.webassemblyModuleFilename!,
trustedTypes: output.trustedTypes!
trustedTypes: output.trustedTypes!,
sourceMapFilename: output.sourceMapFilename!
};
}

Expand Down
3 changes: 3 additions & 0 deletions packages/rspack/src/config/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,9 @@ const applyOutputDefaults = (
output.uniqueName!.replace(/[^a-zA-Z0-9\-#=_/@.%]+/g, "_") || "webpack"
);
}
F(output, "sourceMapFilename", () => {
return "[file].map";
});
};

const applyExternalsPresetsDefaults = (
Expand Down
1 change: 1 addition & 0 deletions packages/rspack/src/config/normalization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export const getNormalizedRspackOptions = (
importFunctionName: output.importFunctionName,
iife: output.iife,
module: output.module,
sourceMapFilename: output.sourceMapFilename,
library: libraryBase && {
type:
output.libraryTarget !== undefined
Expand Down
12 changes: 12 additions & 0 deletions packages/rspack/src/config/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,15 @@ module.exports = {
}
]
},
SourceMapFilename: {
description:
"Specifies the filename of output files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.",
oneOf: [
{
$ref: "#/definitions/FilenameTemplate"
}
]
},
FilenameTemplate: {
description:
"Specifies the filename template of output files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.",
Expand Down Expand Up @@ -1192,6 +1201,9 @@ module.exports = {
$ref: "#/definitions/TrustedTypes"
}
]
},
sourceMapFilename: {
$ref: "#/definitions/SourceMapFilename"
}
}
},
Expand Down
3 changes: 3 additions & 0 deletions packages/rspack/src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export interface Output {
chunkLoading?: string | false;
enabledChunkLoadingTypes?: string[];
trustedTypes?: true | string | TrustedTypes;
sourceMapFilename?: SourceMapFilename;
}
export type Path = string;
export type PublicPath = "auto" | RawPublicPath;
Expand All @@ -175,6 +176,7 @@ export type ChunkLoadingGlobal = string;
export type Library = LibraryName | LibraryOptions;
export type StrictModuleErrorHandling = boolean;
export type OutputModule = boolean;
export type SourceMapFilename = FilenameTemplate;
export type Iife = boolean;
export type Clean = boolean;
export interface LibraryCustomUmdCommentObject {
Expand Down Expand Up @@ -258,6 +260,7 @@ export interface OutputNormalized {
chunkLoading?: string | false;
enabledChunkLoadingTypes?: string[];
trustedTypes?: TrustedTypes;
sourceMapFilename?: SourceMapFilename;
/**
* Algorithm used for generation the hash (see node.js crypto package).
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack/tests/Defaults.unittest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1056,4 +1056,4 @@ describe("snapshots", () => {
`)
);
});
export {};
export { };
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import fs from "fs";
import path from "path";
it("source-map-filename/name should same", async function () {
import("./two");
expect(
fs.readdirSync(path.resolve(__dirname, "")).includes("main.js.map")
).toBe(true);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 2;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/** @type {import("../../../../src/index").RspackOptions} */
module.exports = {
entry: {
main: "./index"
},
devtool: "source-map",
output: {
filename: "[name].js",
sourceMapFilename: "[name].js.map"
}
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
it("should have a relative url to the source-map", function() {
it("should have a relative url to the source-map", function () {
var fs = require("fs");
var source = fs.readFileSync(__filename, "utf-8");
var match = /sourceMappingURL\s*=\s*(.*)/.exec(source);
expect(match[1]).toBe("bundle0.js.map");
});

it("should have a relative url to the source-map with prefix", function(done) {
require.ensure([], function(require) {
it("should have a relative url to the source-map with prefix", function (done) {
require.ensure([], function (require) {
global.expect = expect;
require("./test.js");
done();
Expand Down

0 comments on commit 28156f6

Please sign in to comment.