-
#87
c145a72
Thanks @demiazz! - replacesass
withsass-embedded
-
#85
1bdf32b
Thanks @demiazz! - addforge
bin and update dependencies
-
#87
c145a72
Thanks @demiazz! - replacesass
withsass-embedded
-
#85
1bdf32b
Thanks @demiazz! - addforge
bin and update dependencies
-
#68
eb1414c
Thanks @dependabot! - updatevite
to fix vulnerabilities
-
#57
d3c40d7
Thanks @demiazz! - enablememo
by default for SVGR transformations -
#60
5611ead
Thanks @demiazz! - update target node up to 20.x
-
#62
bcd685a
Thanks @demiazz! - emulate Vite's environment variablesThe
vanilla-extract
usesesbuild
under the hood with CJS format. In that case, if you import any code with usage ofimport
.We assume usage only
import.meta.env.DEV
,import.meta.env.PROD
andimport.meta.env.MODE
variables in bundler user's code and emulate only it with defining constants.But this constants working only in compile time when CSS is generated and based on mode in which the
forge
is running at compilation moment.Be careful when use code which based on that variables in your
vanilla-extract
styles. -
#57
d3c40d7
Thanks @demiazz! - added support of transformation of SVG component name withsvgrComponentName
option.By default, SVGR uses
Svg<CamelCaseFileName>
name for components. You can override this behaviour throughsvgrComponentName
options, which should be function of format(svgrName: string) => string
.Example:
export default { // ... svgrComponentName(name) { return `Ui${name.slice(3)}Icon`; }, // ... };
If you have a file
column.svg
then component name isSvgColumn
by default. But with config from about the name will beUiColumnIcon
.If you use memoization it looks like:
import { memo } from 'react'; const UiColumnIcon = (props) => { // ... }; const Memo = memo(UiColumnIcon); export { Memo as ReactComponent };
This option doesn't affect named exports.
-
#57
d3c40d7
Thanks @demiazz! - allow to appenddisplayName
for SVGR components.By default, SVGR doesn't append
displayName
for exported components. You can add this behaviour throughsvgrDisplayName
option, which should be function of format(componentName: string) => string | { displayName: string; isDebugOnly?: boolean }
.When function is returns string, then
isDebugOnly
equals tofalse
.The
componentName
is name of component itself (before memoization if enabled). If you providesvgrComponentName
option, then result of applying this function iscomponentName
.The
isDebugOnly
enables wrapping the assignment in Vite compatible condition.// `isDebugOnly` = false Component.displayName = 'scope(ComponentDisplayName)'; // `isDebugOnly` = true if (import.meta.env.DEV) { Component.displayName = `scope(ComponentDisplayName)`; }
If memoization is enabled, then the
displayName
will be assigned to the memoized component:const Component = (props) => { // ... }; const Memo = memo(Component); Memo.displayName = `scope(ComponentDisplayName)`;
-
#62
bcd685a
Thanks @demiazz! - emulate Vite's environment variablesThe
vanilla-extract
usesesbuild
under the hood with CJS format. In that case, if you import any code with usage ofimport
.We assume usage only
import.meta.env.DEV
,import.meta.env.PROD
andimport.meta.env.MODE
variables in bundler user's code and emulate only it with defining constants.But this constants working only in compile time when CSS is generated and based on mode in which the
forge
is running at compilation moment.Be careful when use code which based on that variables in your
vanilla-extract
styles.
-
#57
d3c40d7
Thanks @demiazz! - added support of transformation of SVG component name withsvgrComponentName
option.By default, SVGR uses
Svg<CamelCaseFileName>
name for components. You can override this behaviour throughsvgrComponentName
options, which should be function of format(svgrName: string) => string
.Example:
export default { // ... svgrComponentName(name) { return `Ui${name.slice(3)}Icon`; }, // ... };
If you have a file
column.svg
then component name isSvgColumn
by default. But with config from about the name will beUiColumnIcon
.If you use memoization it looks like:
import { memo } from 'react'; const UiColumnIcon = (props) => { // ... }; const Memo = memo(UiColumnIcon); export { Memo as ReactComponent };
This option doesn't affect named exports.
-
#57
d3c40d7
Thanks @demiazz! - allow to appenddisplayName
for SVGR components.By default, SVGR doesn't append
displayName
for exported components. You can add this behaviour throughsvgrDisplayName
option, which should be function of format(componentName: string) => string | { displayName: string; isDebugOnly?: boolean }
.When function is returns string, then
isDebugOnly
equals tofalse
.The
componentName
is name of component itself (before memoization if enabled). If you providesvgrComponentName
option, then result of applying this function iscomponentName
.The
isDebugOnly
enables wrapping the assignment in Vite compatible condition.// `isDebugOnly` = false Component.displayName = 'scope(ComponentDisplayName)'; // `isDebugOnly` = true if (import.meta.env.DEV) { Component.displayName = `scope(ComponentDisplayName)`; }
If memoization is enabled, then the
displayName
will be assigned to the memoized component:const Component = (props) => { // ... }; const Memo = memo(Component); Memo.displayName = `scope(ComponentDisplayName)`;
- #36
8bb0af7
Thanks @demiazz! - add correct handling of user defineddisplayName
property when Storybook docs are generated
-
#32
a92544c
Thanks @demiazz! - addedcssClassPrefix
optionThe option can be boolean or string.
If string option is used, then it will be used as simple template with following placeholders:
[full-name]
- full package name (with scope if it presented);[scope]
- package scope if presented or an empty string;[name]
- package name without scope.
The prefix has format
[full-name]__
by default or when option istrue
.When package name is
awesome-ui
, then:- when the option is
[full-name]__
, then the prefix isawesome_ui__
; - when the option is
[scope]__
, then the prefix is__
; - when the option is
[scope]__[name]__
, then the prefix is__awesome_ui__
.
When package name is
@awesome-ui/theme
, then:- when the option is
[full-name]__
, then the prefix isawesome_ui_theme_
; - when the option is
[scope]__
, then the prefix isawesome_ui__
; - when the option is
[scope]__[name]__
, then the prefix isawesome_ui__theme__
.
-
#32
a92544c
Thanks @demiazz! - uses short CSS classes format for CSS Modules andvanilla-extract
in production mode
-
#23
d81e5d4
Thanks @demiazz! - don't wrap SVG components withReact.memo
by defaultIf you need to change this behaviour, you can use
.svgrrc
files, which supported out of the box, instead ofexportType
,namedExport
andsvgo
options. They are set up by theforge
itself.
-
#14
b0d7f4c
Thanks @demiazz! - mergebuild
andwatch
commands.The
watch
command has been replaced with-w,--watch
option. Also, we replace platform command with-t,--target
option.You should change:
forge watch node
to the following code:
forge build --target node --watch
-
#14
b0d7f4c
Thanks @demiazz! - add support of configuration fileYou can use configuration file. We're looking for:
- a
forge
property in thepackage.json
; - a JSON or YAML
.forgerc
file; - an
.forgerc
file with.json
,.yaml
,.yml
,.js
,.mjs
or.cjs
- any of the above two inside a .config subdirectory;
- a
forge.config.js
,forge.config.mjs
, orforge.config.cjs
file.
Look at example of JSON configuration:
{ "$schema": "https://github.com/ReTable/forge/blob/main/schemas/forgerc.json", "target": "node", "entry": "index", "check": true, "typings": true, "postBuild": "touch lib/meta.js", "build": { "production": true }, "watch": { "production": false, "storybook": true } }
- a
-
#14
b0d7f4c
Thanks @demiazz! - add support of post build hooksYou can use one or more post build hooks:
forge build --target node --post-build "touch lib/index.js" --post-build "touch index.d.ts":"typings"
-
#14
b0d7f4c
Thanks @demiazz! - addinit
commandYou can generate
.forgerc
withinit
command.Example:
forge init --target node
-
#12
0813828
Thanks @demiazz! - add support of multiple entriesYou can use
--entry
option to define entry points.The
--entry
option has the following syntax:--entry <in>[:<out>]
. You can use this option more than one time to define multiple entries.By default, the
forge
always searches<packageRoot>/src/index.tsx
or<packageRoot>/src/index.ts
entry point, and always bundles it to the<packageRoot>/lib/index.js
.The following command:
$ forge build browser
is equivalent to this command:
$ forge build browser --entry index
We allow to define input module as path to file or as path to module. A given path will be automatically prepended by
./src/
path before it will be transferred to theesbuild
.If you provide a module path, then the
forge
will search entry point in different ways.For example, look at the next command:
$ forge build browser --entry nodes
The
forge
will search entry point in the following order:<packageRoot>/src/nodes.tsx
<packageRoot>/src/nodes.ts
<packageRoot>/src/nodes/index.tsx
<packageRoot>/src/nodes/index.ts
By default, the
forge
uses module path relative to the<packageRoot>/src
directory.For example, look at this command:
$ forge build browser --entry nodes
The
forge
create<packageRoot>/lib/nodes.js
bundle independent of entry point (nodes.ts
ornodes/index.ts
).But if you call it in the following style:
$ forge build browser --entry nodes/index
Then the
<packageRoot>/lib/nodes/index.js
will be created.Also, don't provide
.js
extension for output entry. It will be added automatically.But even if you provide it, then we automatically remove it before calling of
esbuild
to prevent creating a file with doubled.js
extension.Support of multiple entries enables code splitting feature to share the code inside a bundled library.
It creates ESM modules with shared code and uses them in bundles.
Each JS bundle will automatically import own CSS bundle in beginning of file if a CSS bundle is exists.
IMPORTANT: This feature not working with CSS. Yes, your imports from CSS modules or
vanilla-extract
will be shared, but own CSS bundle will be created for each JS bundle, even they have a similar styles inside. Hashed classes will be identical in all CSS bundles too. Keep it in mind.
-
#4
8dddd8d
Thanks @demiazz! - adds support of packages resolve in the SassThe
forge
resolves external packages through~<pkg>
urls.Example:
@use '~@tabula/ui-theme' as theme; .root { background-color: theme.$color--primary; }
It will search
<pkg>
in dependencies through Node.jsrequire
, and try to readsass
field in thepackage.json
of the founded package.Example:
{ "name": "@tabula/ui-theme", "sass": "./sass/index.scss" }
will be resolved to the
<node_modules>/@tabula/ui-theme/sass/index.scss
.