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

alias not working #85

Closed
ilovejs opened this issue Aug 18, 2021 · 16 comments
Closed

alias not working #85

ilovejs opened this issue Aug 18, 2021 · 16 comments

Comments

@ilovejs
Copy link

ilovejs commented Aug 18, 2021

main.js

const path = require("path")
const reactRefresh = require("@vitejs/plugin-react-refresh")

module.exports = {
    stories: [
        // "../src/**/*.stories.@(js|jsx|ts|tsx)"
        "../src/components/**/*.stories.@(ts|tsx)",
    ],
    // addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
    core: {
        builder: "storybook-builder-vite",
    },
    resolve: {
        alias: [
            {
                find: "@",
                replacement: path.resolve(__dirname, "./src"),
            },
            {
                find: "@assets",
                replacement: path.resolve(__dirname, "./src/assets"),
            },
            {
                find: "@components",
                replacement: path.resolve(__dirname, "../src/components"),
            },
        ],
    },
    async viteFinal(config, { configType }) {
        // customize the Vite config here
        config.resolve.alias.foo = "bar"

        reactRefresh()

        return config
    },
}

If use yarn run not storybook, config like https://github.com/vitejs/vite/issues/279 work run.
But i believe vite.config.ts != main.js. This plugin can't handle some features like vite.config.ts

Requirement:

[1] show case how to use reactRefresh plugin like we did in vite.config.ts. Cuz reactRefresh is a must for react to work in ite. In vite. Also mention, there is another plugin @vite/vue should be imported if develop vue.

[2] support vite-tsconfig-paths in storybook. So, we can have alias support (there may be quite way to solve, this is the major feature needs to be, for storybook to work with alias)

vite.config.ts

import { defineConfig } from "vite"
// import tsconfigPaths from "vite-tsconfig-paths"
import reactRefresh from "@vitejs/plugin-react-refresh"
// import envCompatible from "vite-plugin-env-compatible"
import path from "path"

export default defineConfig({
    plugins: [reactRefresh()],
    build: {
        outDir: "build",
    },
    // alias: {
    //     "@": path.resolve(__dirname, "./src"),
    // },
    // resolve: {
    alias: [
        {
            find: "@",
            replacement: path.resolve(__dirname, "./src"),
        },
        {
            find: "@assets",
            replacement: path.resolve(__dirname, "./src/assets"),
        },
        {
            find: "@components",
            replacement: path.resolve(__dirname, "./src/components"),
        },
    ],
    // },
    // plugins: [tsconfigPaths(), envCompatible(/* options */), reactRefresh()],
})

tsconfig.json

{
    "compilerOptions": {
        "allowJs": true,
        "allowSyntheticDefaultImports": true,
        "baseUrl": "src",
        "paths": {
          "@components/*": ["./components/*"],
          "@assets/*": ["./assets/*"],
        },
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "isolatedModules": true,
        "jsx": "react-jsx",
        "lib": ["dom", "dom.iterable", "esnext"],
        "module": "esnext",
        "moduleResolution": "node",
        "noEmit": true,
        "noFallthroughCasesInSwitch": true,
        "resolveJsonModule": true,
        "skipLibCheck": true,
        "strict": true,
        "target": "es5",
        "types": ["node", "vite/client"]
    },
    "include": ["./src"]
}

@ThinCats
Copy link

In the function viteFinal(config, { configType }), the parameter config is the config object for vite, which is used by storybook-builder-vite. You can return a new config object.

// main.js

module.exports = {
  async viteFinal(config, { configType }) {
    return {
      ...config,
      resolve: {
        alias: [
          {
            find: "@",
            replacement: path.resolve(__dirname, "./src"),
          },
          {
            find: "@assets",
            replacement: path.resolve(__dirname, "./src/assets"),
          },
          {
            find: "@components",
            replacement: path.resolve(__dirname, "./src/components"),
          },
        ],
      },
    };
  },
};

If you want to reuse the project's vite.config.js, you can use the API mergeConfig and loadConfigFromFile exposed by vite.

const { loadConfigFromFile, mergeConfig } = require("vite");

module.exports = {
	...
  async viteFinal(config, { configType }) {
    const { config: userConfig } = await loadConfigFromFile(
      path.resolve(__dirname, "../vite.config.ts")
    );

    return mergeConfig(config, {
      ...userConfig,
      // manually specify plugins to avoid conflict
      plugins: [],
    });
  },
};

@eirslett
Copy link
Collaborator

☝️ this is the right answer

@konsalex
Copy link

konsalex commented May 6, 2022

The above answer for v6.4.21 did not work for me, while this one worked fine in Stack Overflow

// .storybook/main.js
const path = require("path");
const tsconfigPaths = require("vite-tsconfig-paths").default;

module.exports = {
  "stories": [
    "../frontend/**/*.stories.mdx",
    "../frontend/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions"
  ],
  "framework": "@storybook/react",
  "core": {
    "builder": "storybook-builder-vite"
  },
  /**
   * A option exposed by storybook-builder-vite for customising the Vite config.
   * @see https://github.com/eirslett/storybook-builder-vite#customize-vite-config
   * @param {import("vite").UserConfig} config
   * @see https://vitejs.dev/config/
   */
  viteFinal: async (config) => {
    config.plugins.push(
      /** @see https://github.com/aleclarson/vite-tsconfig-paths */
      tsconfigPaths({
        // My tsconfig.json isn't simply in viteConfig.root,
        // so I've passed an explicit path to it:
        projects: [path.resolve(path.dirname(__dirname), "frontend", "tsconfig.json")],
      })
    );
    
    return config;
  },
}

@abcd-ca
Copy link

abcd-ca commented May 30, 2022

Perhaps loadConfigFromFile changed since this answer but now the first arg is not the path to your project's vite.config.ts but instead an env string (which comes from configType.

    const { config: userConfig } = await loadConfigFromFile(configType,
      path.resolve(__dirname, "../src/client/vite.config.ts")
    );

@coolcorexix
Copy link

My config is somehow neater than what's mentioned but still works: https://stackoverflow.com/a/73105465/9814737

const tsconfigPaths = require("vite-tsconfig-paths");
...
module.exports = {
  ...
  async viteFinal(config) {
    return {
      ...config,
      plugins: [...config.plugins, tsconfigPaths.default()],
    };
  },
};

@Adam-Collier
Copy link

Adam-Collier commented Sep 1, 2022

I came across a similar problem recently but for plugins not pulling through and fixed it with the following:

async viteFinal(config) {
    // pull in our root config
    const { config: mainConfig } = await loadConfigFromFile(
      path.resolve(__dirname, "../vite.config.ts")
    );

    // we need to exclude @vitejs/plugin-react from the plugins to prevent a conflict
    // @vitejs/plugin-react is an array of objects so we can exclude it by checking for a name key
    const filteredPlugins = mainConfig.plugins.filter(item => item.name);

    return mergeConfig(config, {
      resolve: {
        alias: { "@": path.resolve(__dirname, "../src") },
      },
      plugins: [...filteredPlugins]
    });
  },

@Miguel-Bento-Github
Copy link

Perhaps loadConfigFromFile changed since this answer but now the first arg is not the path to your project's vite.config.ts but instead an env string (which comes from configType.

    const { config: userConfig } = await loadConfigFromFile(configType,
      path.resolve(__dirname, "../src/client/vite.config.ts")
    );

Where does configType come from?
Do you have an example on what you pass there?

@IanVS
Copy link
Member

IanVS commented Oct 19, 2022

Where does configType come from?

It can be destructured from the second callback parameter of viteFinal:

async viteFinal(config, { configType }) {

@elsangedy
Copy link

import * as path from 'path'
import tsconfigPaths from 'vite-tsconfig-paths'
// or
const path = require('path');
const tsconfigPaths = require('vite-tsconfig-paths').default;

viteFinal: async (config) => {
  config.plugins.push(
    /** @see https://github.com/aleclarson/vite-tsconfig-paths */
    tsconfigPaths({
      projects: [path.resolve(path.dirname(__dirname), 'tsconfig.json')],
    })
  );
  
  return config;
},

@dawood8080
Copy link

I was facing an error when trying to use path.resolve, regardless I was importing it properly:
const { path } = require("path");

I solved it by importing reolve() directly by const { resolve } = require("path");
and using resolve() instead of path.resolve() in the code.

I hope it helps anyone facing the same issue.

@qnrjs42
Copy link

qnrjs42 commented Mar 27, 2023

If you want to reuse the project's vite.config.js, you can use the API mergeConfig and loadConfigFromFile exposed by vite.

// .storybook/main.cjs
const { loadConfigFromFile, mergeConfig } = require("vite");

module.exports = {
	...
  async viteFinal(config, { configType }) {
    const { config: userConfig } = await loadConfigFromFile(
      path.resolve(__dirname, "../vite.config.ts")
    );

    return mergeConfig(config, {
      ...userConfig,
      // manually specify plugins to avoid conflict
      plugins: [],
    });
  },
};

Good Work!

"vite": "^4.0.0",
"@storybook/react": "^6.5.16",

@IanVS
Copy link
Member

IanVS commented Mar 27, 2023

Also note that storybook 7.0 will use your project's vite.config file automatically.

@dshelters
Copy link

Also note that storybook 7.0 will use your project's vite.config file automatically.

I am using storybook@7.6.3, and I had to implement @Adam-Collier's solution because storybook did not pick up my alias as defined in my vite.config.ts. Tests, tsc, and eslint all did, however.

@IanVS
Copy link
Member

IanVS commented Dec 13, 2023

@dshelters do you use a nonstandard project directory structure? If you could share a reproduction I can take a quick look.

@luiguild
Copy link

@IanVS I'm just created a new project from scratch with the latest version and I can confirm that storybook is not getting my aliases as defined in my vite.config.mts

@tugay-radity
Copy link

My problem was related to react-docgen-typescript it was not crawling types correctly in autodocs. adding baseUrl to reactDocgenTypescriptOptions.compilerOptions fixed the problem.

    reactDocgenTypescriptOptions: {
      // Speeds up Storybook build time
      compilerOptions: {
        baseUrl: 'src', // newly added 
        allowSyntheticDefaultImports: false,
        esModuleInterop: false,
      },
      // Makes union prop types like variant and size appear as select controls
      shouldExtractLiteralValuesFromEnum: true,
      // Makes string and boolean types that can be undefined appear as inputs and switches
      shouldRemoveUndefinedFromOptional: true,
      // Filter out third-party props from node_modules except @mui packages
      propFilter: (prop) =>
        prop.parent ? !/node_modules\/(?!@mui)/.test(prop.parent.fileName) : true,
    }, 

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