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

Css extraction issue with transpiled code #620

Open
pksorensen opened this issue Nov 14, 2024 · 4 comments
Open

Css extraction issue with transpiled code #620

pksorensen opened this issue Nov 14, 2024 · 4 comments

Comments

@pksorensen
Copy link

I have used my project (quickform-core) in another project and used css extraction without problems. But in a new project i am just hitting my head against the wall for hours now not able to figure out why.

my next.config.js


import { env } from "process";

import { withGriffelCSSExtraction } from '@griffel/next-extraction-plugin';

/** @type {import('next').NextConfig} */
const nextConfig =  {
    output: env.NODE_ENV === "production" ? 'standalone' : undefined,
    compress: false,
    experimental: {
        instrumentationHook: true,
        swcPlugins: [['fluentui-next-appdir-directive', { paths: ['@griffel', '@fluentui', '@eavfw'] }]],
    },
    transpilePackages: ["@fluentui/react-components", '@eavfw/quickform-core', '@eavfw/quickform-input-select', '@eavfw/query'],
 

    webpack(config) {
        config.module.rules.unshift({
            test: /\.(js|jsx)$/,
            exclude: /node_modules/,
            use: [
                {
                    loader: '@griffel/webpack-loader',
                },
            ],
        });

        // If your project uses TypeScript
        config.module.rules.unshift({
            test: /\.(ts|tsx)$/,
            exclude: /node_modules/,
            use: [
                {
                    loader: '@griffel/webpack-loader',
                    options: {
                        babelOptions: {
                            presets: [
                                "next/babel"
                            ]
                        },
                    },
                },
            ],
        });
       
        return config;
    },
     
};

export default withGriffelCSSExtraction()(nextConfig);

and i am getting the below error. I tried to identify the difference between my working project and the new project, but so far they are very similar.

Any hint to help me find the root cause would be nice.

@EAVFW\quickform-core is basically a bunch of typescritp files distributed by npm

./src/components/quickform/GroupOnlineQuickform.tsx
C:\dev\go\qp\node_modules\@eavfw\quickform-core\src\index.ts:1
(function (exports) { export * from "./components";
                      ^^^^^^

SyntaxError: Unexpected token 'export'
    at new Script (node:vm:117:7)
    at Module.evaluate (C:\dev\go\qp\node_modules\@linaria\babel-preset\lib\module.js:280:20)
    at require.Object.assign.ensure (C:\dev\go\qp\node_modules\@linaria\babel-preset\lib\module.js:214:13)
    at C:\dev\go\qp\apps\GroupOnline.QuotationPlatformHost\src\components\quickform-container\goTokens.tsx:4:22
    at C:\dev\go\qp\apps\GroupOnline.QuotationPlatformHost\src\components\quickform-container\goTokens.tsx:17:3
    at Script.runInContext (node:vm:149:12)
    at Module.evaluate (C:\dev\go\qp\node_modules\@linaria\babel-preset\lib\module.js:283:12)
    at require.Object.assign.ensure (C:\dev\go\qp\node_modules\@linaria\babel-preset\lib\module.js:214:13)
    at C:\dev\go\qp\apps\GroupOnline.QuotationPlatformHost\src\components\quickform\GroupOnlineQuickform.tsx:3:17
    at C:\dev\go\qp\apps\GroupOnline.QuotationPlatformHost\src\components\quickform\GroupOnlineQuickform.tsx:40:3
    at Script.runInContext (node:vm:149:12)
    at Module.evaluate (C:\dev\go\qp\node_modules\@linaria\babel-preset\lib\module.js:283:12)
    at evaluate (C:\dev\go\qp\node_modules\@griffel\babel-preset\src\utils\evaluatePathsInVM.js:22:9)
    at evaluatePathsInVM (C:\dev\go\qp\node_modules\@griffel\babel-preset\src\utils\evaluatePathsInVM.js:80:21)
    at evaluatePaths (C:\dev\go\qp\node_modules\@griffel\babel-preset\src\utils\evaluatePaths.js:22:51)
    at PluginPass.exit (C:\dev\go\qp\node_modules\@griffel\babel-preset\src\transformPlugin.js:186:59)
    at newFn (C:\dev\go\qp\node_modules\@babel\traverse\lib\visitors.js:172:14)
    at NodePath._call (C:\dev\go\qp\node_modules\@babel\traverse\lib\path\context.js:49:20)
    at NodePath.call (C:\dev\go\qp\node_modules\@babel\traverse\lib\path\context.js:39:18)
    at NodePath.visit (C:\dev\go\qp\node_modules\@babel\traverse\lib\path\context.js:96:8)
    at TraversalContext.visitQueue (C:\dev\go\qp\node_modules\@babel\traverse\lib\context.js:90:16)
    at TraversalContext.visitSingle (C:\dev\go\qp\node_modules\@babel\traverse\lib\context.js:66:19)
    at TraversalContext.visit (C:\dev\go\qp\node_modules\@babel\traverse\lib\context.js:113:19)
    at traverseNode (C:\dev\go\qp\node_modules\@babel\traverse\lib\traverse-node.js:22:17)
    at traverse (C:\dev\go\qp\node_modules\@babel\traverse\lib\index.js:53:34)
    at transformFile (C:\dev\go\qp\node_modules\@babel\core\lib\transformation\index.js:82:31)
    at transformFile.next (<anonymous>)
    at run (C:\dev\go\qp\node_modules\@babel\core\lib\transformation\index.js:24:12)
    at run.next (<anonymous>)
    at C:\dev\go\qp\node_modules\@babel\core\lib\transform-ast.js:23:33
    at Generator.next (<anonymous>)
    at evaluateSync (C:\dev\go\qp\node_modules\gensync\index.js:251:28)
    at sync (C:\dev\go\qp\node_modules\gensync\index.js:89:14)
    at stopHiding - secret - don't use this - v1 (C:\dev\go\qp\node_modules\@babel\core\lib\errors\rewrite-stack-trace.js:47:12)
    at Object.transformFromAstSync (C:\dev\go\qp\node_modules\@babel\core\lib\transform-ast.js:43:83)
    at transformSync (C:\dev\go\qp\node_modules\@griffel\webpack-loader\src\transformSync.js:21:35)
    at Object.webpackLoader (C:\dev\go\qp\node_modules\@griffel\webpack-loader\src\webpackLoader.js:80:52)

Import trace for requested module:
./src/components/quickform/GroupOnlineQuickform.tsx


> Build failed because of webpack errors
@pksorensen
Copy link
Author

I was able to track down the issue, in the new project we was importing our tokens .

in a component if using tokens from library then the error surfaces, but if we just type out the var(...) manually things work

"use client";
import { QuickForm, QuickFormDefinition, QuickFormProvider, quickformtokens } from "@eavfw/quickform-core"
import { QuotationFormStatus } from "../../eav/quotationFormTemplates.api";
import { makeStaticStyles, makeStyles } from "@fluentui/react-components";

import { goTokens } from "../../style/tokens";
import { useState } from "react";
import { useServerInsertedHTML } from "next/navigation";

const useQuickformStyles = makeStyles({
    slide: {
        margin: "2rem auto",
        maxWidth: "72rem",
    },
    ending: {
        alignItems: "center",
        lineHeight: "1.4"
    },
    slideButton: {
        paddingLeft: '25px',
        paddingRight: '25px',
        borderRadius: quickformtokens.questionBorderRadius // 'var(--slide-button-border-radius,100px)' This works when typed directly, not imported tokens
    },
    banner: {
        padding: '1rem 0',
        marginBottom: '4px',
        display: 'flex',
        justifyContent: 'center',
        fontWeight: '900',
        borderRadius: '20px',
        boxShadow: 'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
    }
});

Library Tokens

/* Color-scheme is inspired by Material Design (https://m2.material.io/design/color/the-color-system.html#color-theme-creation) */

import { log } from "console";
import { resolveQuickFormService } from "../services/QuickFormServices";
import { camelToKebabCase, defineVariables } from "../utils/quickformUtils";
import { defaultQuickFormTokens } from "./defaultQuickFormTokens";

type Color = string;
type FontSize = string;
type Gap = string;
type NuancedColor<T extends string> = `${T}${'Darker' | 'Lighter'}${'' | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900}`;
type QuickFormStructuredColorProperties = 'primary' | 'onPrimary' | 'secondary' | 'onSecondary' | 'background' | 'onBackground' | 'surface' | 'onSurface' | 'error' | 'onError';

type QuickFormTokensBase = {
    /* Pure colors */
    white: Color,
    black: Color,
    warning: Color,
    success: Color,
    info: Color,
    questionPlaceholderColor: Color,

    /* Structured colors */
    primary: Color,
    onPrimary: Color,
    secondary: Color,
    onSecondary: Color,
    background: Color,
    onBackground: Color,
    surface: Color,
    onSurface: Color,
    error: Color,
    onError: Color,

    /* Typography */
    fontFamily: string,
    headlineFontSize: FontSize;
    subtitleFontSize: FontSize;
    paragraphFontSize: FontSize;
    paragraphMobileFontSize: FontSize;
    btnFontSize: FontSize,
    btnEnterKeyTextFontSize: FontSize,
    btnFontWeight: number,
    multilineTextFontSize: FontSize,
    multilineTextMobileFontSize: FontSize,

    questionHeadlineFontSize: FontSize,
    questionHeadlineFontWeight: number,
    questionParagraphFontSize: FontSize,
    questionNumberFontSize: FontSize,
    questionInputFontSize: FontSize,

    /* Structural properties */
    gap1: Gap,
    gap2: Gap,
    gap4: Gap,
    disabledOpacity: number;
    dividerOpacity: number;
    lowEmphasisOpacity: number;
    mediumEmphasisOpacity: number;
    highEmphasisOpacity: number;

    // Question
    questionBorderRadius: string;
    questionTopMargin: string;
    questionBottomMargin: string;
    questionPadding: string;
    questionInputGap: Gap,
    questionPaddingBottom: string;

    slideButtonIconSize: string;
};

export type QuickFormTokens = QuickFormTokensBase & {
    [Property in NuancedColor<QuickFormStructuredColorProperties>]?: Color;
};

/**
 * Defines and returns the CSS variables for the Quick Form based on provided tokens.
 * This function merges user-defined tokens with the default tokens, ensuring that
 * any customizations are applied on top of the defaults. The result is a flat object
 * where keys are CSS variable names in camel-case, suitable for direct use in styling objects that use React.CSSProperties.
 * 
 * @param tokens - An array of token objects. Each object can partially override the default tokens.
 * @returns A flat object with CSS camel-case variable names as keys and their corresponding values.
 */
export const defineQuickFormTokens = (...tokens: Array<Partial<QuickFormTokens>>) => {
    const logger = resolveQuickFormService("logger");
    logger.log("Merging Quick Form tokens.", tokens);
    // Merges and overrides default tokens with provided ones in reverse order for precedence.
    const mergedTokens = tokens.reduce((prevTokens, currentTokens) => {
        logger.log("Merging currentTokens into prevTokens", prevTokens, currentTokens);
        return ({
            ...prevTokens,
            ...currentTokens,
        })
    }, defaultQuickFormTokens);

    // Ensures merged tokens are camelCase CSS variables that React.CSSProperties can use and return.
    return defineVariables(mergedTokens);
};




/**
 * Provides QuickForm with css tokens to be passed around in the components so they refer to the same css variables that are loaded into the QuickFormProvider upon application instantiation.
 * @returns A flat object with CSS variables in camelCase that have corresponding values provided as kebab-case tokens variable names that map to globally defined colors.
 * See example: quickformtokens = { onPrimary: "var(--on-primary)"; onSecondary: "var(--on-secondary)" } and so on. You get the idea.
 */
export const quickformtokens = camelToKebabCase(defaultQuickFormTokens);

@pksorensen
Copy link
Author

@layershifter - are there any special way one need to export tokens for them to be used. I looked at fluentui and it seems it is just a dictionary of key value - i changed above to the same to not have any logic like the cameltoKebabCase, but the result is the same.

Need to figure out how to export tokens from my lib so it can be used in consumer project with css extraction

@layershifter
Copy link
Member

(will follow up on Monday 👀 )

@layershifter
Copy link
Member

@pksorensen do I correctly understand that you have a monorepo:

Image

Are you using Yarn Workspaces? NPM?

Or should @eavfw/quickform-core come from a separate repo? (i.e. external dependency)


Monorepo case

It's odd that it gets resolved into node_modules/*, should be C:\dev\go\qp\packages\SMTH.

External dependency

In this case, it seems that @eavfw/quickform-core it's not bundled properly. Something like tsup (with bundling both ESM & CJS) + proper fields in package.json (i.e. main & module) should solve this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants