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 module umd globals #6717

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ output.mjs
index.g.js
output.json
output.ts
output.*.ts
output.css
output.min.css
output.html
Expand Down
6 changes: 3 additions & 3 deletions crates/swc_ecma_transforms_module/src/umd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ where
C: Comments,
{
as_folder(Umd {
config: config.build(cm.clone()),
config: config.build(),
unresolved_mark,
cm,
resolver: Resolver::Default,
Expand Down Expand Up @@ -68,7 +68,7 @@ where
C: Comments,
{
as_folder(Umd {
config: config.build(cm.clone()),
config: config.build(),
unresolved_mark,
cm,
resolver: Resolver::Real { base, resolver },
Expand Down Expand Up @@ -445,7 +445,7 @@ where
let global_dep = {
let dep_name = self.config.global_name(&src_path);
let global = global.clone();
if is_valid_prop_ident(&dep_name) {
if is_valid_prop_ident(&dep_name) || dep_name.eq("_") {
global.make_member(quote_ident!(dep_name))
} else {
global.computed_member(quote_str!(dep_name))
Expand Down
107 changes: 73 additions & 34 deletions crates/swc_ecma_transforms_module/src/umd/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use std::collections::HashMap;
use inflector::Inflector;
use serde::{Deserialize, Serialize};
use swc_atoms::JsWord;
use swc_common::{errors::HANDLER, sync::Lrc, FileName, SourceMap};
use swc_ecma_ast::{Expr, Ident};
use swc_ecma_parser::{parse_file_as_expr, Syntax};
use swc_cached::regex::CachedRegex;
use swc_common::FileName;
use swc_ecma_ast::Ident;
use swc_ecma_utils::quote_ident;

use super::super::util;
Expand All @@ -14,58 +14,97 @@ use super::super::util;
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct Config {
#[serde(default)]
pub globals: HashMap<String, String>,
pub globals: Option<HashMap<String, String>>,

#[serde(default)]
pub exact_globals: Option<Vec<(String, String)>>,

#[serde(flatten, default)]
pub config: util::Config,
}

fn reduce_src(src: &JsWord) -> JsWord {
let mut out = src.clone();

let js_ext_regex = CachedRegex::new(r#"\.([cm]?[jt]s|[jt]sx)$"#).unwrap();

if out.contains('/') {
out = out.split('/').last().unwrap().into();
}

out = JsWord::from(js_ext_regex.replace(&out, ""));

out = out.to_camel_case().into();
if (out).eq("") {
out = JsWord::from("_");
}
out
}

impl Config {
pub(super) fn build(self, cm: Lrc<SourceMap>) -> BuiltConfig {
pub(super) fn build(self) -> BuiltConfig {
BuiltConfig {
config: self.config,
globals: self
.globals
.into_iter()
.map(|(k, v)| {
let parse = |s| {
let fm = cm
.new_source_file(FileName::Custom(format!("<umd-config-{}.js>", s)), s);

parse_file_as_expr(
&fm,
Syntax::default(),
Default::default(),
None,
&mut vec![],
)
.map_err(|e| {
if HANDLER.is_set() {
HANDLER.with(|h| e.into_diagnostic(h).emit())
}
})
.unwrap()
};
(k, parse(v))
})
.collect(),
exact_globals: self.exact_globals.as_ref().map(|globals| {
globals
.iter()
.filter_map(|(glb_matcher, glb_map)| {
let regex = CachedRegex::new(glb_matcher);
match regex {
Ok(reg) => Some((reg, glb_map.to_string())),
_ => None,
}
})
.collect()
}),
globals: self.globals.map(|globals| {
globals
.iter()
.map(|(glb_matcher, glb_map)| {
let reduced_matcher =
reduce_src(&JsWord::from(glb_matcher.as_str())).to_string();
(reduced_matcher, glb_map.to_string())
})
.collect()
}),
}
}
}
#[derive(Clone)]
pub(super) struct BuiltConfig {
#[allow(dead_code)]
pub globals: HashMap<String, Box<Expr>>,
pub globals: Option<HashMap<String, String>>,
pub exact_globals: Option<Vec<(CachedRegex, String)>>,
pub config: util::Config,
}

impl BuiltConfig {
pub fn global_name(&self, src: &JsWord) -> JsWord {
if !src.contains('/') {
return src.to_camel_case().into();
if let Some(globals) = &self.exact_globals {
let matched_mapped_global = globals.iter().find_map(|(regex, map_str)| {
if regex.is_match(src) {
return Some(map_str);
}
None
});

if let Some(matched) = matched_mapped_global {
return JsWord::from(matched.as_str());
}

return reduce_src(src);
}

let mapped_src: JsWord = reduce_src(src);

if let Some(globals) = &self.globals {
if globals.contains_key(&mapped_src.to_string()) {
let mapped_global = globals.get(&mapped_src.to_string()).unwrap();
return JsWord::from(mapped_global.as_str());
}
}

src.split('/').last().unwrap().to_camel_case().into()
mapped_src
}

pub fn determine_export_name(&self, filename: FileName) -> Ident {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"@eduzz/houston-tokens/variables/breakpoints",
"@emotion/css"
], factory);
else if (global = typeof globalThis !== "undefined" ? globalThis : global || self) factory(global.input = {}, global[""], global.styled, global.breakpoints, global.css);
else if (global = typeof globalThis !== "undefined" ? globalThis : global || self) factory(global.input = {}, global._, global.styled, global.breakpoints, global.css);
})(this, function(exports, _, _styled, _breakpoints, _css) {
"use strict";
Object.defineProperty(exports, "__esModule", {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"exports",
"./dep.js"
], factory);
else if (global = typeof globalThis !== "undefined" ? globalThis : global || self) factory(global.input = {}, global.depJs);
else if (global = typeof globalThis !== "undefined" ? globalThis : global || self) factory(global.input = {}, global.dep);
})(this, function(exports, _depJs) {
"use strict";
Object.defineProperty(exports, "__esModule", {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Dot imports and there global reducing

```js
import dot from '.';
import twoDots from '..';
```

In

```js
if (global = typeof globalThis !== "undefined" ? globalThis : global || self) factory(global.input = {}, global.sparkle, global.worldLevel, global.stormJs, global.phenomenaLevels, global.indexJs, global[""]);
```

```js
global[""]
```
is wrong.

Babel convert it to

```js
global._
```

This PR about `issue-6697`does fix it. As it was part of the work.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import sparkle from '@themagician/sparkle';
import worldLevel from './worldLevel';
import storm from './storm.js';
import phenomenaLevels from './phenomena.levels';
import index from './some/index.js';
import dot from '.';
import twoDots from '..';

export class Hello {
message(to) {
console.log(`Hello ${to.toString()}!`);
}
}

export class World {
runExperiement() {
const seed = storm(worldLevel(), phenomenaLevels());
twoDots(dot(index()));
sparkle(seed);
}

toString() {
return `World ${worldLevel()} ${storm()}`;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
define([
"require",
"exports",
"@themagician/sparkle",
"./worldLevel",
"./storm.js",
"./phenomena.levels",
"./some/index.js",
".",
".."
], function(require, exports, _sparkle, _worldLevel, _stormJs, _phenomenaLevels, _indexJs, _, _1) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
Hello: ()=>Hello,
World: ()=>World
});
_sparkle = /*#__PURE__*/ _interopRequireDefault(_sparkle);
_worldLevel = /*#__PURE__*/ _interopRequireDefault(_worldLevel);
_stormJs = /*#__PURE__*/ _interopRequireDefault(_stormJs);
_phenomenaLevels = /*#__PURE__*/ _interopRequireDefault(_phenomenaLevels);
_indexJs = /*#__PURE__*/ _interopRequireDefault(_indexJs);
_ = /*#__PURE__*/ _interopRequireDefault(_);
_1 = /*#__PURE__*/ _interopRequireDefault(_1);
class Hello {
message(to) {
console.log(`Hello ${to.toString()}!`);
}
}
class World {
runExperiement() {
const seed = (0, _stormJs.default)((0, _worldLevel.default)(), (0, _phenomenaLevels.default)());
(0, _1.default)((0, _.default)((0, _indexJs.default)()));
(0, _sparkle.default)(seed);
}
toString() {
return `World ${(0, _worldLevel.default)()} ${(0, _stormJs.default)()}`;
}
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
Hello: ()=>Hello,
World: ()=>World
});
const _sparkle = /*#__PURE__*/ _interopRequireDefault(require("@themagician/sparkle"));
const _worldLevel = /*#__PURE__*/ _interopRequireDefault(require("./worldLevel"));
const _stormJs = /*#__PURE__*/ _interopRequireDefault(require("./storm.js"));
const _phenomenaLevels = /*#__PURE__*/ _interopRequireDefault(require("./phenomena.levels"));
const _indexJs = /*#__PURE__*/ _interopRequireDefault(require("./some/index.js"));
const _ = /*#__PURE__*/ _interopRequireDefault(require("."));
const _1 = /*#__PURE__*/ _interopRequireDefault(require(".."));
class Hello {
message(to) {
console.log(`Hello ${to.toString()}!`);
}
}
class World {
runExperiement() {
const seed = (0, _stormJs.default)((0, _worldLevel.default)(), (0, _phenomenaLevels.default)());
(0, _1.default)((0, _.default)((0, _indexJs.default)()));
(0, _sparkle.default)(seed);
}
toString() {
return `World ${(0, _worldLevel.default)()} ${(0, _stormJs.default)()}`;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
(function(global, factory) {
if (typeof module === "object" && typeof module.exports === "object") factory(exports, require("@themagician/sparkle"), require("./worldLevel"), require("./storm.js"), require("./phenomena.levels"), require("./some/index.js"), require("."), require(".."));
else if (typeof define === "function" && define.amd) define([
"exports",
"@themagician/sparkle",
"./worldLevel",
"./storm.js",
"./phenomena.levels",
"./some/index.js",
".",
".."
], factory);
else if (global = typeof globalThis !== "undefined" ? globalThis : global || self) factory(global.input = {}, global.sparkle, global.worldLevel, global.storm, global.phenomenaLevels, global.index, global._, global._);
})(this, function(exports, _sparkle, _worldLevel, _stormJs, _phenomenaLevels, _indexJs, _, _1) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
Hello: ()=>Hello,
World: ()=>World
});
_sparkle = /*#__PURE__*/ _interopRequireDefault(_sparkle);
_worldLevel = /*#__PURE__*/ _interopRequireDefault(_worldLevel);
_stormJs = /*#__PURE__*/ _interopRequireDefault(_stormJs);
_phenomenaLevels = /*#__PURE__*/ _interopRequireDefault(_phenomenaLevels);
_indexJs = /*#__PURE__*/ _interopRequireDefault(_indexJs);
_ = /*#__PURE__*/ _interopRequireDefault(_);
_1 = /*#__PURE__*/ _interopRequireDefault(_1);
class Hello {
message(to) {
console.log(`Hello ${to.toString()}!`);
}
}
class World {
runExperiement() {
const seed = (0, _stormJs.default)((0, _worldLevel.default)(), (0, _phenomenaLevels.default)());
(0, _1.default)((0, _.default)((0, _indexJs.default)()));
(0, _sparkle.default)(seed);
}
toString() {
return `World ${(0, _worldLevel.default)()} ${(0, _stormJs.default)()}`;
}
}
});
Loading