Skip to content

Commit

Permalink
feat: add support for output.crossOriginLoading config (#2632)
Browse files Browse the repository at this point in the history
* feat: add basic support for output.crossOriginLoading

* feat: allow crossOriginLoading to be false value

* chore: update CrossOriginLoading::Disable

* test: add e2e test for crossOriginLoading

* chore: update pnpm-lock.yaml

* Update crates/rspack_plugin_runtime/src/runtime_module/css_loading.rs

* Update crates/rspack_plugin_runtime/src/runtime_module/load_script.rs

* Update crates/rspack_plugin_runtime/src/runtime_module/css_loading.rs

* Update crates/rspack_plugin_runtime/src/runtime_module/load_script.rs

---------

Co-authored-by: underfin <likui6666666@gmail.com>
  • Loading branch information
chenjiahan and underfin authored Apr 6, 2023
1 parent a9e1adf commit d007971
Show file tree
Hide file tree
Showing 26 changed files with 239 additions and 12 deletions.
6 changes: 6 additions & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,11 @@ export interface RawLibraryOptions {
umdNamedDefine?: boolean
auxiliaryComment?: RawLibraryAuxiliaryComment
}
export interface RawCrossOriginLoading {
type: boolean | string
stringPayload?: string
boolPayload?: boolean
}
export interface RawOutputOptions {
path: string
publicPath: string
Expand All @@ -312,6 +317,7 @@ export interface RawOutputOptions {
webassemblyModuleFilename: string
filename: string
chunkFilename: string
crossOriginLoading: RawCrossOriginLoading
cssFilename: string
cssChunkFilename: string
uniqueName: string
Expand Down
8 changes: 8 additions & 0 deletions crates/rspack/tests/fixtures/.hash/expected/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ __webpack_require__.l = function loadScript(url, done, key, chunkId) {
script.timeout = 120;
// script.setAttribute("data-webpack", dataWebpackPrefix + key);
script.src = url;

if (false && script.src.indexOf(window.location.origin + '/') !== 0) {
script.crossOrigin = false;
}
}
inProgress[url] = [done];
var onScriptComplete = function (prev, event) {
Expand Down Expand Up @@ -253,6 +257,10 @@ var loadStylesheet = (chunkId, url, done, hmr) => {
link.setAttribute(loadingAttribute, 1);
link.rel = "stylesheet";
link.href = url;

if (false && link.href.indexOf(window.location.origin + '/') !== 0) {
link.crossOrigin = false;
}
}
var onLinkComplete = (prev, event) => {
link.onerror = link.onload = null;
Expand Down
30 changes: 28 additions & 2 deletions crates/rspack_binding_options/src/options/raw_output.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use napi_derive::napi;
use rspack_core::{
BoxPlugin, LibraryAuxiliaryComment, LibraryName, LibraryOptions, OutputOptions, PluginExt,
WasmLoading,
BoxPlugin, CrossOriginLoading, LibraryAuxiliaryComment, LibraryName, LibraryOptions,
OutputOptions, PluginExt, WasmLoading,
};
use serde::Deserialize;

Expand Down Expand Up @@ -71,6 +71,30 @@ impl From<RawLibraryOptions> for LibraryOptions {
}
}

#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
#[napi(object)]
pub struct RawCrossOriginLoading {
#[napi(ts_type = "boolean | string")]
pub r#type: String,
pub string_payload: Option<String>,
pub bool_payload: Option<bool>,
}

impl From<RawCrossOriginLoading> for CrossOriginLoading {
fn from(value: RawCrossOriginLoading) -> Self {
match value.r#type.as_str() {
"string" => Self::Enable(
value
.string_payload
.expect("should have a string_payload when RawCrossOriginLoading.type is \"string\""),
),
"bool" => Self::Disable,
_ => unreachable!(),
}
}
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
#[napi(object)]
Expand All @@ -83,6 +107,7 @@ pub struct RawOutputOptions {
pub webassembly_module_filename: String,
pub filename: String,
pub chunk_filename: String,
pub cross_origin_loading: RawCrossOriginLoading,
pub css_filename: String,
pub css_chunk_filename: String,
pub unique_name: String,
Expand Down Expand Up @@ -117,6 +142,7 @@ impl RawOptionsApply for RawOutputOptions {
unique_name: self.unique_name,
filename: self.filename.into(),
chunk_filename: self.chunk_filename.into(),
cross_origin_loading: self.cross_origin_loading.into(),
css_filename: self.css_filename.into(),
css_chunk_filename: self.css_chunk_filename.into(),
library: self.library.map(Into::into),
Expand Down
16 changes: 16 additions & 0 deletions crates/rspack_core/src/options/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct OutputOptions {
pub unique_name: String,
pub filename: Filename,
pub chunk_filename: Filename,
pub cross_origin_loading: CrossOriginLoading,
pub css_filename: Filename,
pub css_chunk_filename: Filename,
pub library: Option<LibraryOptions>,
Expand Down Expand Up @@ -53,6 +54,21 @@ impl From<&str> for WasmLoadingType {
}
}

#[derive(Debug)]
pub enum CrossOriginLoading {
Disable,
Enable(String),
}

impl std::fmt::Display for CrossOriginLoading {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CrossOriginLoading::Disable => write!(f, "false"),
CrossOriginLoading::Enable(value) => write!(f, "'{}'", value),
}
}
}

pub const NAME_PLACEHOLDER: &str = "[name]";
pub const PATH_PLACEHOLDER: &str = "[path]";
pub const EXT_PLACEHOLDER: &str = "[ext]";
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 @@ -48,6 +48,7 @@ async fn loader_test(actual: impl AsRef<Path>, expected: impl AsRef<Path>) {
wasm_loading: rspack_core::WasmLoading::Disable,
webassembly_module_filename: rspack_core::Filename::from_str("").expect("TODO:"),
chunk_filename: rspack_core::Filename::from_str("").expect("TODO:"),
cross_origin_loading: rspack_core::CrossOriginLoading::Disable,
unique_name: Default::default(),
css_chunk_filename: rspack_core::Filename::from_str("").expect("TODO:"),
css_filename: rspack_core::Filename::from_str("").expect("TODO:"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,12 @@ impl RuntimeModule for CssLoadingRuntimeModule {
&stringify_chunks(&initial_chunk_ids_with_css, 0)
)));

source.add(RawSource::from(include_str!("runtime/css_loading.js")));
source.add(RawSource::from(
include_str!("runtime/css_loading.js").replace(
"__CROSS_ORIGIN_LOADING_PLACEHOLDER__",
&compilation.options.output.cross_origin_loading.to_string(),
),
));

if with_loading {
source.add(RawSource::from(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ impl RuntimeModule for LoadScriptRuntimeModule {
self.id
}

fn generate(&self, _compilation: &Compilation) -> BoxSource {
RawSource::from(include_str!("runtime/load_script.js")).boxed()
fn generate(&self, compilation: &Compilation) -> BoxSource {
RawSource::from(include_str!("runtime/load_script.js").replace(
"__CROSS_ORIGIN_LOADING_PLACEHOLDER__",
&compilation.options.output.cross_origin_loading.to_string(),
))
.boxed()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ var loadStylesheet = (chunkId, url, done, hmr) => {
link.setAttribute(loadingAttribute, 1);
link.rel = "stylesheet";
link.href = url;

if (__CROSS_ORIGIN_LOADING_PLACEHOLDER__ && link.href.indexOf(window.location.origin + '/') !== 0) {
link.crossOrigin = __CROSS_ORIGIN_LOADING_PLACEHOLDER__;
}
}
var onLinkComplete = (prev, event) => {
link.onerror = link.onload = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var inProgress = {};

// var dataWebpackPrefix = "webpack:";
// loadScript function to load a script via script tag
__webpack_require__.l = function loadScript(url, done, key, chunkId) {
Expand Down Expand Up @@ -29,6 +30,10 @@ __webpack_require__.l = function loadScript(url, done, key, chunkId) {
script.timeout = 120;
// script.setAttribute("data-webpack", dataWebpackPrefix + key);
script.src = url;

if (__CROSS_ORIGIN_LOADING_PLACEHOLDER__ && script.src.indexOf(window.location.origin + '/') !== 0) {
script.crossOrigin = __CROSS_ORIGIN_LOADING_PLACEHOLDER__;
}
}
inProgress[url] = [done];
var onScriptComplete = function (prev, event) {
Expand Down
1 change: 1 addition & 0 deletions crates/rspack_testing/src/test_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ impl TestConfig {
output: c::OutputOptions {
filename: c::Filename::from_str(&self.output.filename).expect("Should exist"),
chunk_filename: c::Filename::from_str(&self.output.chunk_filename).expect("Should exist"),
cross_origin_loading: rspack_core::CrossOriginLoading::Disable,
css_filename: c::Filename::from_str(&self.output.css_filename).expect("Should exist"),
css_chunk_filename: c::Filename::from_str(&self.output.css_chunk_filename)
.expect("Should exist"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@rspack-test/cross-origin-loading",
"private": true
}
24 changes: 24 additions & 0 deletions packages/playground/fixtures/cross-origin-loading/rspack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/** @type { import('@rspack/core').RspackOptions } */

module.exports = {
context: __dirname,
mode: "development",
entry: "./src/index.js",
stats: "none",
builtins: {
html: [
{
template: "./src/index.html"
}
],
define: {
"process.env.NODE_ENV": JSON.stringify("development")
}
},
output: {
crossOriginLoading: "anonymous"
},
devServer: {
port: 3000
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default "foo";
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head> </head>
<body>
<div id="root"></div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Set the public path of async chunk to a cross-origin URL
__webpack_public_path__ = "https://cdn.example.com/";

// Avoid removing script tag
Node.prototype.removeChild = () => {};

import("./foo.js");
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { wait } from "../../utils";

test("should set crossOrigin to anonymous for script tag correctly", async () => {
await wait(50);
const scripts = await page.$$("script");

const crossOrigins = await Promise.all(
scripts.map(script => script.getAttribute("crossorigin"))
);

expect(crossOrigins).toEqual(["anonymous", null]);
});
2 changes: 1 addition & 1 deletion packages/playground/fixtures/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function waitingUpdate(
}
}

async function wait(time: number) {
export async function wait(time: number) {
return new Promise(resolve => {
setTimeout(() => {
resolve(undefined);
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/scripts/setupFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ beforeAll(async () => {
return;
}
const testDir = path.resolve(__dirname, "../temp", caseName);
const configPath = path.resolve(testDir, "webpack.config.js");
const configPath = path.resolve(testDir, "rspack.config.js");
const configFile = require(configPath);
const compiler = createCompiler(configFile);
server = new RspackDevServer(compiler.options.devServer ?? {}, compiler);
Expand Down
11 changes: 11 additions & 0 deletions packages/rspack/src/config/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import assert from "assert";
import { normalizeStatsPreset } from "../stats";
import { isNil } from "../util";
import {
CrossOriginLoading,
EntryNormalized,
Experiments,
ExternalItem,
Expand Down Expand Up @@ -144,6 +145,15 @@ function getRawResolve(resolve: Resolve): RawOptions["resolve"] {
};
}

function getRawCrossOriginLoading(
crossOriginLoading: CrossOriginLoading
): RawOptions["output"]["crossOriginLoading"] {
if (typeof crossOriginLoading === "boolean") {
return { type: "bool", boolPayload: crossOriginLoading };
}
return { type: "string", stringPayload: crossOriginLoading };
}

function getRawOutput(output: OutputNormalized): RawOptions["output"] {
const wasmLoading = output.wasmLoading!;
return {
Expand All @@ -152,6 +162,7 @@ function getRawOutput(output: OutputNormalized): RawOptions["output"] {
assetModuleFilename: output.assetModuleFilename!,
filename: output.filename!,
chunkFilename: output.chunkFilename!,
crossOriginLoading: getRawCrossOriginLoading(output.crossOriginLoading!),
cssFilename: output.cssFilename!,
cssChunkFilename: output.cssChunkFilename!,
uniqueName: output.uniqueName!,
Expand Down
2 changes: 2 additions & 0 deletions packages/rspack/src/config/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ const applyOutputDefaults = (
// });
return Array.from(enabledWasmLoadingTypes);
});

D(output, "crossOriginLoading", false);
};

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 @@ -49,6 +49,7 @@ export const getNormalizedRspackOptions = (
publicPath: output.publicPath,
filename: output.filename,
chunkFilename: output.chunkFilename,
crossOriginLoading: output.crossOriginLoading,
cssFilename: output.cssFilename,
cssChunkFilename: output.cssChunkFilename,
assetModuleFilename: output.assetModuleFilename,
Expand Down
7 changes: 7 additions & 0 deletions packages/rspack/src/config/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ module.exports = {
}
]
},
CrossOriginLoading: {
description: "This option enables cross-origin loading of chunks.",
enum: [false, "anonymous", "use-credentials"]
},
Context: {
description:
"The base directory (absolute path!) for resolving the `entry` option. If `output.pathinfo` is set, the included pathinfo is shortened to this directory.",
Expand Down Expand Up @@ -987,6 +991,9 @@ module.exports = {
chunkFilename: {
$ref: "#/definitions/ChunkFilename"
},
crossOriginLoading: {
$ref: "#/definitions/CrossOriginLoading"
},
cssChunkFilename: {
$ref: "#/definitions/CssChunkFilename"
},
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 @@ -114,6 +114,7 @@ export interface Output {
publicPath?: PublicPath;
filename?: Filename;
chunkFilename?: ChunkFilename;
crossOriginLoading?: CrossOriginLoading;
cssFilename?: CssFilename;
cssChunkFilename?: CssChunkFilename;
assetModuleFilename?: AssetModuleFilename;
Expand All @@ -140,6 +141,7 @@ export type AssetModuleFilename = string;
export type WebassemblyModuleFilename = string;
export type Filename = FilenameTemplate;
export type ChunkFilename = FilenameTemplate;
export type CrossOriginLoading = false | "anonymous" | "use-credentials";
export type CssFilename = FilenameTemplate;
export type CssChunkFilename = FilenameTemplate;
export type FilenameTemplate = string;
Expand Down Expand Up @@ -205,6 +207,7 @@ export interface OutputNormalized {
publicPath?: PublicPath;
filename?: Filename;
chunkFilename?: ChunkFilename;
crossOriginLoading?: CrossOriginLoading;
cssFilename?: CssFilename;
cssChunkFilename?: CssChunkFilename;
assetModuleFilename?: AssetModuleFilename;
Expand Down
Loading

0 comments on commit d007971

Please sign in to comment.