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

fix: trusted type with devtool eval #7866

Merged
merged 1 commit into from
Sep 12, 2024
Merged
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
3 changes: 3 additions & 0 deletions crates/rspack_core/src/dependency/dependency_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub enum DependencyType {
NewUrl,
// new Worker()
NewWorker,
// create script url
CreateScriptUrl,
// import.meta.webpackHot.accept
ImportMetaHotAccept,
// import.meta.webpackHot.decline
Expand Down Expand Up @@ -118,6 +120,7 @@ impl DependencyType {
DependencyType::CjsSelfReference => "cjs self exports reference",
DependencyType::NewUrl => "new URL()",
DependencyType::NewWorker => "new Worker()",
DependencyType::CreateScriptUrl => "create script url",
DependencyType::ImportMetaHotAccept => "import.meta.webpackHot.accept",
DependencyType::ImportMetaHotDecline => "import.meta.webpackHot.decline",
DependencyType::ModuleHotAccept => "module.hot.accept",
Expand Down
32 changes: 29 additions & 3 deletions crates/rspack_plugin_devtool/src/eval_dev_tool_module_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rspack_core::{
ApplyContext, BoxModule, ChunkInitFragments, ChunkUkey, Compilation, CompilationParams,
CompilerCompilation, CompilerOptions, Plugin, PluginContext,
};
use rspack_core::{CompilationAdditionalTreeRuntimeRequirements, RuntimeGlobals};
use rspack_error::Result;
use rspack_hash::RspackHash;
use rspack_hook::{plugin, plugin_hook};
Expand Down Expand Up @@ -83,6 +84,7 @@ async fn eval_devtool_plugin_compilation(
hooks
.inline_in_runtime_bailout
.tap(eval_devtool_plugin_inline_in_runtime_bailout::new(self));

Ok(())
}

Expand Down Expand Up @@ -135,11 +137,16 @@ fn eval_devtool_plugin_render_module_content(
.trim_start_matches('/')
)
);
// TODO: Implement support for the trustedTypes option.
// This will depend on the additionalModuleRuntimeRequirements hook.

let module_content =
simd_json::to_string(&format!("{source}{footer}")).expect("failed to parse string");
RawSource::from(format!(
"eval({});",
simd_json::to_string(&format!("{source}{footer}")).expect("failed to parse string")
if compilation.options.output.trusted_types.is_some() {
format!("{}({})", RuntimeGlobals::CREATE_SCRIPT, module_content)
} else {
module_content
}
))
.boxed()
};
Expand Down Expand Up @@ -183,10 +190,29 @@ impl Plugin for EvalDevToolModulePlugin {
.compiler_hooks
.compilation
.tap(eval_devtool_plugin_compilation::new(self));
ctx
.context
.compilation_hooks
.additional_tree_runtime_requirements
.tap(eval_devtool_plugin_additional_tree_runtime_requirements::new(self));
Ok(())
}
}

#[plugin_hook(CompilationAdditionalTreeRuntimeRequirements for EvalDevToolModulePlugin)]
async fn eval_devtool_plugin_additional_tree_runtime_requirements(
&self,
compilation: &mut Compilation,
_chunk_ukey: &ChunkUkey,
runtime_requirements: &mut RuntimeGlobals,
) -> Result<()> {
if compilation.options.output.trusted_types.is_some() {
runtime_requirements.insert(RuntimeGlobals::CREATE_SCRIPT);
}

Ok(())
}

// https://tc39.es/ecma262/#sec-encode
// UNESCAPED is combined by ALWAYS_UNESCAPED and ";/?:@&=+$,#"
static UNESCAPED: LazyLock<UkeySet<u32>> = LazyLock::new(|| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use derivative::Derivative;
use futures::future::join_all;
use rspack_core::{
rspack_sources::{BoxSource, MapOptions, RawSource, Source, SourceExt},
ApplyContext, BoxModule, ChunkInitFragments, ChunkUkey, Compilation, CompilationParams,
CompilerCompilation, CompilerOptions, ModuleIdentifier, Plugin, PluginContext,
ApplyContext, BoxModule, ChunkInitFragments, ChunkUkey, Compilation,
CompilationAdditionalTreeRuntimeRequirements, CompilationParams, CompilerCompilation,
CompilerOptions, ModuleIdentifier, Plugin, PluginContext, RuntimeGlobals,
};
use rspack_error::Result;
use rspack_hash::RspackHash;
Expand Down Expand Up @@ -173,9 +174,15 @@ fn eval_source_map_devtool_plugin_render_module_content(
let base64 = rspack_base64::encode_to_string(&map_buffer);
let footer =
format!("\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,{base64}");
let module_content =
simd_json::to_string(&format!("{source}{footer}")).expect("should convert to string");
RawSource::from(format!(
"eval({});",
simd_json::to_string(&format!("{source}{footer}")).expect("should convert to string")
if compilation.options.output.trusted_types.is_some() {
format!("{}({})", RuntimeGlobals::CREATE_SCRIPT, module_content)
} else {
module_content
}
))
.boxed()
};
Expand Down Expand Up @@ -205,6 +212,20 @@ fn eval_source_map_devtool_plugin_inline_in_runtime_bailout(
Ok(Some("the eval-source-map devtool is used.".to_string()))
}

#[plugin_hook(CompilationAdditionalTreeRuntimeRequirements for EvalSourceMapDevToolPlugin)]
async fn eval_source_map_devtool_plugin_additional_tree_runtime_requirements(
&self,
compilation: &mut Compilation,
_chunk_ukey: &ChunkUkey,
runtime_requirements: &mut RuntimeGlobals,
) -> Result<()> {
if compilation.options.output.trusted_types.is_some() {
runtime_requirements.insert(RuntimeGlobals::CREATE_SCRIPT);
}

Ok(())
}

#[async_trait::async_trait]
impl Plugin for EvalSourceMapDevToolPlugin {
fn name(&self) -> &'static str {
Expand All @@ -221,6 +242,11 @@ impl Plugin for EvalSourceMapDevToolPlugin {
.compiler_hooks
.compilation
.tap(eval_source_map_devtool_plugin_compilation::new(self));
ctx
.context
.compilation_hooks
.additional_tree_runtime_requirements
.tap(eval_source_map_devtool_plugin_additional_tree_runtime_requirements::new(self));
Ok(())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use rspack_core::{
AsContextDependency, AsModuleDependency, Compilation, Dependency, DependencyCategory,
DependencyId, DependencyTemplate, DependencyType, RealDependencyLocation, RuntimeGlobals,
RuntimeSpec, TemplateContext, TemplateReplaceSource,
};

#[derive(Debug, Clone)]
pub struct CreateScriptUrlDependency {
id: DependencyId,
range: RealDependencyLocation,
range_path: (u32, u32),
}

impl CreateScriptUrlDependency {
pub fn new(range: RealDependencyLocation, range_path: (u32, u32)) -> Self {
Self {
id: DependencyId::new(),
range,
range_path,
}
}
}

impl Dependency for CreateScriptUrlDependency {
fn id(&self) -> &DependencyId {
&self.id
}

fn category(&self) -> &DependencyCategory {
&DependencyCategory::Worker
}

fn dependency_type(&self) -> &DependencyType {
&DependencyType::CreateScriptUrl
}

fn range(&self) -> Option<&RealDependencyLocation> {
Some(&self.range)
}

fn could_affect_referencing_module(&self) -> rspack_core::AffectType {
rspack_core::AffectType::False
}
}

impl DependencyTemplate for CreateScriptUrlDependency {
fn apply(
&self,
source: &mut TemplateReplaceSource,
code_generatable_context: &mut TemplateContext,
) {
code_generatable_context
.runtime_requirements
.insert(RuntimeGlobals::CREATE_SCRIPT_URL);

source.insert(
self.range_path.0,
format!("{}(", RuntimeGlobals::CREATE_SCRIPT_URL).as_str(),
None,
);
source.insert(self.range_path.1, ")", None);
}

fn dependency_id(&self) -> Option<DependencyId> {
Some(self.id)
}

fn update_hash(
&self,
_hasher: &mut dyn std::hash::Hasher,
_compilation: &Compilation,
_runtime: Option<&RuntimeSpec>,
) {
}
}

impl AsModuleDependency for CreateScriptUrlDependency {}
impl AsContextDependency for CreateScriptUrlDependency {}
2 changes: 2 additions & 0 deletions crates/rspack_plugin_javascript/src/dependency/worker/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod create_script_url_dependency;
pub use create_script_url_dependency::CreateScriptUrlDependency;
use rspack_core::{
get_chunk_from_ukey, AsContextDependency, Compilation, Dependency, DependencyCategory,
DependencyId, DependencyTemplate, DependencyType, ExtendedReferencedExport, ModuleDependency,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use super::{
JavascriptParserPlugin,
};
use crate::{
dependency::WorkerDependency,
dependency::{CreateScriptUrlDependency, WorkerDependency},
utils::object_properties::get_literal_str_by_obj_prop,
visitors::{JavascriptParser, TagInfoData},
webpack_comment::try_extract_webpack_magic_comment,
Expand Down Expand Up @@ -118,6 +118,16 @@ fn add_dependencies(
})));

parser.blocks.push(Box::new(block));

if parser.compiler_options.output.trusted_types.is_some() {
parser
.dependencies
.push(Box::new(CreateScriptUrlDependency::new(
span.into(),
parsed_path.range,
)));
}

if let Some(range) = range {
parser
.presentational_dependencies
Expand Down
46 changes: 46 additions & 0 deletions crates/rspack_plugin_runtime/src/runtime_module/create_script.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use rspack_collections::Identifier;
use rspack_core::{
impl_runtime_module,
rspack_sources::{BoxSource, RawSource, SourceExt},
Compilation, RuntimeGlobals, RuntimeModule,
};

#[impl_runtime_module]
#[derive(Debug)]
pub struct CreateScriptRuntimeModule {
id: Identifier,
}

impl Default for CreateScriptRuntimeModule {
fn default() -> Self {
Self::with_default(Identifier::from("webpack/runtime/create_script"))
}
}

impl RuntimeModule for CreateScriptRuntimeModule {
fn name(&self) -> Identifier {
self.id
}

fn generate(&self, compilation: &Compilation) -> rspack_error::Result<BoxSource> {
Ok(
RawSource::from(format!(
r#"
{} = function(script){{
return {};
}};
"#,
RuntimeGlobals::CREATE_SCRIPT,
if compilation.options.output.trusted_types.is_some() {
format!(
"{}().createScript(script)",
RuntimeGlobals::GET_TRUSTED_TYPES_POLICY
)
} else {
"script".to_string()
}
))
.boxed(),
)
}
}
2 changes: 2 additions & 0 deletions crates/rspack_plugin_runtime/src/runtime_module/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod chunk_prefetch_trigger;
mod chunk_preload_trigger;
mod compat_get_default_export;
mod create_fake_namespace_object;
mod create_script;
mod create_script_url;
mod define_property_getters;
mod ensure_chunk;
Expand Down Expand Up @@ -49,6 +50,7 @@ pub use chunk_prefetch_trigger::ChunkPrefetchTriggerRuntimeModule;
pub use chunk_preload_trigger::ChunkPreloadTriggerRuntimeModule;
pub use compat_get_default_export::CompatGetDefaultExportRuntimeModule;
pub use create_fake_namespace_object::CreateFakeNamespaceObjectRuntimeModule;
pub use create_script::CreateScriptRuntimeModule;
pub use create_script_url::CreateScriptUrlRuntimeModule;
pub use define_property_getters::DefinePropertyGettersRuntimeModule;
pub use ensure_chunk::EnsureChunkRuntimeModule;
Expand Down
17 changes: 10 additions & 7 deletions crates/rspack_plugin_runtime/src/runtime_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ use crate::runtime_module::{
chunk_has_css, is_enabled_for_chunk, AsyncRuntimeModule, AutoPublicPathRuntimeModule,
BaseUriRuntimeModule, ChunkNameRuntimeModule, ChunkPrefetchPreloadFunctionRuntimeModule,
CompatGetDefaultExportRuntimeModule, CreateFakeNamespaceObjectRuntimeModule,
CreateScriptUrlRuntimeModule, DefinePropertyGettersRuntimeModule, EnsureChunkRuntimeModule,
GetChunkFilenameRuntimeModule, GetChunkUpdateFilenameRuntimeModule, GetFullHashRuntimeModule,
GetMainFilenameRuntimeModule, GetTrustedTypesPolicyRuntimeModule, GlobalRuntimeModule,
HarmonyModuleDecoratorRuntimeModule, HasOwnPropertyRuntimeModule, LoadScriptRuntimeModule,
MakeNamespaceObjectRuntimeModule, NodeModuleDecoratorRuntimeModule, NonceRuntimeModule,
OnChunkLoadedRuntimeModule, PublicPathRuntimeModule, RelativeUrlRuntimeModule,
RuntimeIdRuntimeModule, SystemContextRuntimeModule,
CreateScriptRuntimeModule, CreateScriptUrlRuntimeModule, DefinePropertyGettersRuntimeModule,
EnsureChunkRuntimeModule, GetChunkFilenameRuntimeModule, GetChunkUpdateFilenameRuntimeModule,
GetFullHashRuntimeModule, GetMainFilenameRuntimeModule, GetTrustedTypesPolicyRuntimeModule,
GlobalRuntimeModule, HarmonyModuleDecoratorRuntimeModule, HasOwnPropertyRuntimeModule,
LoadScriptRuntimeModule, MakeNamespaceObjectRuntimeModule, NodeModuleDecoratorRuntimeModule,
NonceRuntimeModule, OnChunkLoadedRuntimeModule, PublicPathRuntimeModule,
RelativeUrlRuntimeModule, RuntimeIdRuntimeModule, SystemContextRuntimeModule,
};

static GLOBALS_ON_REQUIRE: LazyLock<Vec<RuntimeGlobals>> = LazyLock::new(|| {
Expand Down Expand Up @@ -407,6 +407,9 @@ fn runtime_requirements_in_tree(
compilation
.add_runtime_module(chunk_ukey, CreateScriptUrlRuntimeModule::default().boxed())?;
}
RuntimeGlobals::CREATE_SCRIPT => {
compilation.add_runtime_module(chunk_ukey, CreateScriptRuntimeModule::default().boxed())?;
}
RuntimeGlobals::ON_CHUNKS_LOADED => {
compilation
.add_runtime_module(chunk_ukey, OnChunkLoadedRuntimeModule::default().boxed())?;
Expand Down
Loading
Loading