ionic-team / stencil

A toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, and traditional web developers from a single, framework-agnostic codebase.
https://stenciljs.com
Other
12.6k stars 790 forks source link

Stencil becomes a dependency to project when installing with --legacy-peer-deps #5808

Closed andberg closed 5 months ago

andberg commented 6 months ago

Background I'm working with a designsystem built with Stencil. We've gotten reports from teams using our UI-components that they've had to add Stencil as a dependency (primarily in the pipelines), which confused me. According to the Stencil documentation; "The code generated by Stencil does not rely on Stencil, but rather it generates highly-optimized, framework-free, stand-alone code which runs natively in the browser." from: https://stenciljs.com/docs/faq#what-dependencies-does-the-stencil-runtime-have

Current behavior: When investigating the issue I realized that the teams get the issue when they use the --legacy-peer-deps flag when running npm install.

Steps to reproduce

Locally:

  1. Download repo
  2. npm i
  3. npm run build

Result and expected result Everything works fine

In Pipeline

  1. It follows the step defined in .gitlab-ci.yml file - which are the same as above
  2. In the npm install step add --legacy-peer-deps

Expected Result Everything works just as fine as it is locally

Actual result The job in the pipeline complains Error: Module not found: Error: Can't resolve '@stencil/core/internal/client' You can se the different outcomes in the Pipeline of this project. The ones without --legacy-peer-deps work fine, the other not so fine.

Question or maybe bug-report We have some teams that has som legacy code that need the --legacy-peer-deps flag and the results in that they also have to have Stencil as a dependency. I wonder why. Is this known by you and accepted behavior or is this a bug?

GitHub Reproduction Link: Repo showcasing issue

christian-bromann commented 6 months ago

@andberg thanks for raising the issue!

It seems to me that the package containing the Stencil components (@digi/arbetsformedlingen) has bundled the components using the externalRuntime flag set to true which is the default value. Can you give me more information on how the Stencil configuration of @digi/arbetsformedlingen looks like? I recommend to set this flag to false to have he Stencil compiler create a package bundle so that no dependencies are needed.

andberg commented 5 months ago

Hi! Of course, the main config is here:

import { Config } from '@stencil/core';
import { sass } from '@stencil/sass';

export const StencilBaseConfig: Config = {
    namespace: 'digi-arbetsformedlingen',
    taskQueue: 'async',
  autoprefixCss: false,
  sourceMap: false,
    srcDir: '../src',
    tsconfig: '../tsconfig.json',
    plugins: [
        sass()
    ],
  enableCache: false,
  cacheDir: '../../../.digi/af-stencil',
    outputTargets: [],
    globalStyle: '../src/global/styles/index.scss',
    globalScript: '../src/global/scripts/index.ts',
};

https://gitlab.com/arbetsformedlingen/designsystem/digi/-/blob/develop/libs/arbetsformedlingen/package/stencil.config.ts?ref_type=heads

And then it's imported and enhanced for different environments in these config files https://gitlab.com/arbetsformedlingen/designsystem/digi/-/tree/develop/libs/arbetsformedlingen/package/.config?ref_type=heads The production file looks like

import { Config } from '@stencil/core';
import { StencilBaseConfig } from '../stencil.config';
import { config as AngularConfig } from './stencil.config.angular';
import { config as ReactConfig } from './stencil.config.react';

export const config: Config = {
  ...StencilBaseConfig,
    srcDir: '../src',
    tsconfig: '../tsconfig.json',
    outputTargets: [
        ...(StencilBaseConfig.outputTargets as any),
    ...(AngularConfig.outputTargets as any),
    ...(ReactConfig.outputTargets as any),
        {
            type: 'dist',
            dir: '../dist',
            esmLoaderPath: '../loader',
            copy: [
                { src: 'design-tokens', dest: 'design-tokens' },
                { src: '../../fonts', dest: 'fonts' },
                { src: '../../../shared/styles', dest: 'styles' },
                {
                    src: 'components/**/styles/*.variables.scss',
                    dest: 'design-tokens/components',
                    warn: true
                },
                {
                    src: '__core/**/styles/*.variables.scss',
                    dest: 'design-tokens/components',
                    warn: true
                }
            ]
        },
        {
            type: 'dist-custom-elements',
            dir: '../components',
            customElementsExportBehavior: 'single-export-module',
                        generateTypeDeclarations: true,
            copy: [
                { src: 'design-tokens', dest: 'design-tokens' },
                { src: '../../fonts', dest: 'fonts' },
                {
                    src: 'components/**/styles/*.variables.scss',
                    dest: 'design-tokens/components',
                    warn: true
                },
                {
                    src: '__core/**/styles/*.variables.scss',
                    dest: 'design-tokens/components',
                    warn: true
                }
            ]
        },
        {
            type: 'docs-vscode',
            file: './custom-elements.json'
        },
        {
            type: 'dist-hydrate-script',
            dir: '../hydrate'
        },
        {
            type: 'www',
            serviceWorker: null,
            dir: '../www'
        }
    ],
       extras: {
           enableImportInjection: true
       }
};

I was not part of this project when this was set-up, so am bit of a noob when it comes to Stencil and it's configuration. I've searched the project for externalRuntime and not found it, so I guess it defaults to something. Do you know where in the documentation i can find that setting? I've looked here https://stenciljs.com/docs/v4.7/config but haven't found it.

The complete repo is open source and can be found here https://gitlab.com/arbetsformedlingen/designsystem/digi

christian-bromann commented 5 months ago

I've searched the project for externalRuntime and not found it, so I guess it defaults to something.

Yes, it defaults to true which means that it requires a @stencil/core dependency to be installed.

Do you know where in the documentation i can find that setting?

Yes, it is part of the output target docs: https://stenciljs.com/docs/v4.7/custom-elements#externalruntime. I recommend setting externalRuntime: true in the dist-custom-elements output target setting.

andberg commented 5 months ago

Thank you @christian-bromann, for your response! I will change this in our output target config, try it in my example and get back to you.

christian-bromann commented 5 months ago

@andberg I will go ahead and close this. Let me know if you have any further questions or if you think we could do better in the Stencil docs. Thanks for supporting Stencil!

andberg commented 5 months ago

We are trying a fix for this today. It can be that we've imported from the wrong package in Stencil. I will document the result from our findings here when we have them. :)

andberg commented 5 months ago

@christian-bromann Hi Again! The import changes didn't do anything to this Issue, but by changeing the stencil config to: externalRuntime: false solved our Issue. Before we commit those changes I wonder if this can have some drawbacks that I should be aware of? The documentation is not so clear regarding this. Thank you again for all your help!

christian-bromann commented 5 months ago

@andberg I am not aware of any drawbacks, it very much depends on your use case.

andberg commented 5 months ago

I understand. Then we will discuss it within our team and see what we decide.