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

feat: add script nonce #4975

Merged
merged 1 commit into from
Dec 12, 2023
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/runtime_globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ bitflags! {
const SHARE_SCOPE_MAP = 1 << 52;

const INITIALIZE_SHARING = 1 << 53;

const SCRIPT_NONCE = 1 << 54;
}
}

Expand Down Expand Up @@ -302,6 +304,7 @@ impl RuntimeGlobals {
R::CURRENT_REMOTE_GET_SCOPE => "__webpack_require__.R",
R::SHARE_SCOPE_MAP => "__webpack_require__.S",
R::INITIALIZE_SHARING => "__webpack_require__.I",
R::SCRIPT_NONCE => "__webpack_require__.nc",
r => panic!(
"Unexpected flag `{r:?}`. RuntimeGlobals should only be printed for one single flag."
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub const NON_WEBPACK_REQUIRE: &str = "__non_webpack_require__";
pub const SYSTEM_CONTEXT: &str = "__system_context__";
pub const WEBPACK_SHARE_SCOPES: &str = "__webpack_share_scopes__";
pub const WEBPACK_INIT_SHARING: &str = "__webpack_init_sharing__";
pub const WEBPACK_NONCE: &str = "__webpack_nonce__";

pub struct ApiScanner<'a> {
pub unresolved_ctxt: SyntaxContext,
Expand Down Expand Up @@ -205,6 +206,16 @@ impl Visit for ApiScanner<'_> {
Some(RuntimeGlobals::INITIALIZE_SHARING),
)))
}
WEBPACK_NONCE => {
self
.presentational_dependencies
.push(Box::new(ConstDependency::new(
ident.span.real_lo(),
ident.span.real_hi(),
RuntimeGlobals::SCRIPT_NONCE.name().into(),
Some(RuntimeGlobals::SCRIPT_NONCE),
)));
}
_ => {}
}
}
Expand Down
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 @@ -23,6 +23,7 @@ mod load_script;
mod make_namespace_object;
mod module_chunk_loading;
mod node_module_decorator;
mod nonce;
mod normal;
mod on_chunk_loaded;
mod public_path;
Expand Down Expand Up @@ -57,6 +58,7 @@ pub use load_script::LoadScriptRuntimeModule;
pub use make_namespace_object::MakeNamespaceObjectRuntimeModule;
pub use module_chunk_loading::ModuleChunkLoadingRuntimeModule;
pub use node_module_decorator::NodeModuleDecoratorRuntimeModule;
pub use nonce::NonceRuntimeModule;
pub use normal::NormalRuntimeModule;
pub use on_chunk_loaded::OnChunkLoadedRuntimeModule;
pub use public_path::PublicPathRuntimeModule;
Expand Down
31 changes: 31 additions & 0 deletions crates/rspack_plugin_runtime/src/runtime_module/nonce.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use rspack_core::{
impl_runtime_module,
rspack_sources::{BoxSource, RawSource, SourceExt},
Compilation, RuntimeGlobals, RuntimeModule,
};
use rspack_identifier::Identifier;

#[derive(Debug, Eq)]
pub struct NonceRuntimeModule {
id: Identifier,
}

impl Default for NonceRuntimeModule {
fn default() -> Self {
Self {
id: Identifier::from("webpack/runtime/nonce"),
}
}
}

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

fn generate(&self, _: &Compilation) -> BoxSource {
RawSource::from(format!("{} = undefined;", RuntimeGlobals::SCRIPT_NONCE)).boxed()
}
}

impl_runtime_module!(NonceRuntimeModule);
9 changes: 6 additions & 3 deletions crates/rspack_plugin_runtime/src/runtime_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use crate::runtime_module::{
GetMainFilenameRuntimeModule, GetTrustedTypesPolicyRuntimeModule, GlobalRuntimeModule,
HarmonyModuleDecoratorRuntimeModule, HasOwnPropertyRuntimeModule,
LoadChunkWithBlockRuntimeModule, LoadScriptRuntimeModule, MakeNamespaceObjectRuntimeModule,
NodeModuleDecoratorRuntimeModule, NormalRuntimeModule, OnChunkLoadedRuntimeModule,
PublicPathRuntimeModule, SystemContextRuntimeModule,
NodeModuleDecoratorRuntimeModule, NonceRuntimeModule, NormalRuntimeModule,
OnChunkLoadedRuntimeModule, PublicPathRuntimeModule, SystemContextRuntimeModule,
};

static GLOBALS_ON_REQUIRE: Lazy<Vec<RuntimeGlobals>> = Lazy::new(|| {
Expand All @@ -43,7 +43,7 @@ static GLOBALS_ON_REQUIRE: Lazy<Vec<RuntimeGlobals>> = Lazy::new(|| {
RuntimeGlobals::PUBLIC_PATH,
RuntimeGlobals::BASE_URI,
// RuntimeGlobals::RELATIVE_URL,
// RuntimeGlobals::SCRIPT_NONCE,
RuntimeGlobals::SCRIPT_NONCE,
// RuntimeGlobals::UNCAUGHT_ERROR_HANDLER,
RuntimeGlobals::ASYNC_MODULE,
// RuntimeGlobals::WASM_INSTANCES,
Expand Down Expand Up @@ -378,6 +378,9 @@ impl Plugin for RuntimePlugin {
RuntimeGlobals::SYSTEM_CONTEXT if matches!(&library_type, Some(t) if t == "system") => {
compilation.add_runtime_module(chunk, SystemContextRuntimeModule::default().boxed())
}
RuntimeGlobals::SCRIPT_NONCE => {
compilation.add_runtime_module(chunk, NonceRuntimeModule::default().boxed());
}
_ => {}
}
}
Expand Down
Empty file.
12 changes: 12 additions & 0 deletions packages/rspack/tests/configCases/nonce/not-set-nonce/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
it("should load script without nonce", function () {
__webpack_nonce__ = undefined;
const promise = import(
"./empty?a" /* webpackChunkName: "chunk-without-nonce" */
);

var script = document.head._children.pop();
__non_webpack_require__("./chunk-without-nonce.web.js");
expect(script.getAttribute("nonce")).toBeUndefined();

return promise;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
target: "web",
output: {
chunkFilename: "chunk-without-nonce.web.js",
crossOriginLoading: "anonymous",
trustedTypes: true
},
optimization: {
minimize: false
}
};
Empty file.
12 changes: 12 additions & 0 deletions packages/rspack/tests/configCases/nonce/set-nonce/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
it("should load script with nonce 'nonce1234'", function () {
__webpack_nonce__ = "nonce1234";
const promise = import(
"./empty?a" /* webpackChunkName: "chunk-with-nonce" */
);

var script = document.head._children.pop();
__non_webpack_require__("./chunk-with-nonce.web.js");
expect(script.getAttribute("nonce")).toBe("nonce1234");

return promise;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
target: "web",
output: {
chunkFilename: "chunk-with-nonce.web.js",
crossOriginLoading: "anonymous",
trustedTypes: true
},
optimization: {
minimize: false
}
};
1 change: 0 additions & 1 deletion webpack-test/configCases/web/nonce/test.filter.js

This file was deleted.

Loading