Skip to content

Commit

Permalink
feat: add script nonce (#4975)
Browse files Browse the repository at this point in the history
  • Loading branch information
LingyuCoder authored Dec 12, 2023
1 parent 1ca2e0f commit 711661c
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 4 deletions.
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.

0 comments on commit 711661c

Please sign in to comment.