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

File names dont match with imports in JS files when building --prod #2687

Closed
obrunopolo opened this issue Oct 1, 2020 · 12 comments
Closed
Labels
Resolution: Needs Investigation This PR or Issue should be investigated from the Stencil team

Comments

@obrunopolo
Copy link

obrunopolo commented Oct 1, 2020

Stencil version:

I'm submitting a:

[x] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://stencil-worldwide.herokuapp.com/ or https://forum.ionicframework.com/

Current behavior:

The app works well while using stencil build --serve --dev --watch, but once I build a production version, run a http server on the www folder and open it in the browser, it gets stuck on white screen on 50% of builds. On console I could see error 404, some resources were missing.

Expected behavior:

Production builds should work reliably.

Steps to reproduce:

Create a "Starter app" template and run npm start and npm run build a few times. After each production build, try to open on browser using some http server.

In my case I could see that index.html loads the first hashed js file successfully, but then it try to import 2 non-existing files.

Please note that this may not be related to the hash of file names, because I could reproduce this behavior with hashFileNames: false . In this case, it was importing a file with different content hash.

@ionitron-bot ionitron-bot bot added the triage label Oct 1, 2020
@MarkChrisLevy
Copy link

I can confirm that issue. It is also not related to caching (both in browser and cli "--no-cache" setting).

@obrunopolo
Copy link
Author

obrunopolo commented Oct 6, 2020

@MarkChrisLevy that's correct. I also tryied to use enableCache: false and still get the same error.

Just got this again today:

image

I have to build at least two times to make this work.

@r3dDoX
Copy link

r3dDoX commented Oct 21, 2020

I'm having the same Problem since v2. Opened another issue couple weeks ago: #2671.
I can still reproduce this with 2.1.0

@Scan0815
Copy link

Scan0815 commented Oct 28, 2020

i can also reproduce this on 2.2.0.

if I delete the build directory, a new build works. only if there is already a build in the directory does not work.

@r3dDoX
Copy link

r3dDoX commented Nov 12, 2020

I am still able to reproduce this with 2.3.0

@Scan0815
Copy link

@adamdbradley ,
I'm sorry to speak to you directly, but the error is really annoying, having to constantly delete the build folder in a running project. in version 1 it worked great.

@MrAntix
Copy link
Contributor

MrAntix commented Nov 22, 2020

you can reproduce this with the starter app

npm init stencil 
npm i

npm run build => built index.html still has the app.css and app.js files in the head
npm run build => built index.html has compiled references except the nomodule one

so a second build produces different results

if you delete www, build will give your the first result again

@kevinlandsberg
Copy link

Can reproduce the error in stencil 2.3.0
Always getting 404's for bundle file inside www

@rohanrp
Copy link

rohanrp commented Dec 24, 2020

A temp fix is to delete the dist and www folders before running the build command. e.g

npm install --save-dev del-cli

package.json:
"build": "del-cli --force ./www && del-cli --force ./dist && stencil build --prod",

@MrAntix
Copy link
Contributor

MrAntix commented Jan 29, 2021

you can also use the empty flag in config

    {
      type: 'www',
      dir: 'wwwroot',
      empty: true
    },

@r3dDoX
Copy link

r3dDoX commented Feb 1, 2021

Just tried today with 2.4.0 and I can still reproduce this bug.

@rwaskiewicz rwaskiewicz added Resolution: Needs Investigation This PR or Issue should be investigated from the Stencil team and removed Feature: Compiler labels Mar 25, 2022
alicewriteswrongs added a commit that referenced this issue Oct 26, 2023
This fixes an issue where the `www` build and, in particular, some code
that attempts to inline the entry point for the `www` build into the
`index.html` file that the build outputs, was depending on a file which,
in certain circumstances, would not yet be built. This produced
inconsistency across builds, where the `www` build would pick up and
inline the entry point from the _previous_ build (if the build wasn't
deleted) instead of from the current build.

To go into more detail, prior to this change with the `www` output
target if you did:

```sh
stencil build --dev --watch --serve
```

in a Stencil project and _then_ you ran a build (without deleting
`www/`) like:

```sh
stencil build
```

You'd get a non-working build. Not good!

Why did this happen? We have this function which is called as part of
the `www` build:

https://github.com/ionic-team/stencil/blob/5c4ea3d5354596e5cfb544f91bde7f61de1888b4/src/compiler/html/inline-esm-import.ts#L10-L105

This will basically look for the entry point for the `www` build at
`www/build/project-name.js` and, if it finds it, it will inline that
code in the `index.html` file, reducing the number of JS files that have
to be fetch on page-load by one.

However! Without this change we have a race condition where the lazy
build (which writes the file we're looking for to disk) is not written
until after the `www` build executes. This means that:

- on the first build the entry point is not found, so nothing is inlined
  in the HTML. this produces a working build, but the optimization
  (inlining) is missed.
- on the second build, if `www/` is not deleted then the entry point
  from the _first_ build is found and inlined _or_ if the file is larger
  than a cutoff size then a hashed copy of it will be made and the
  `<script>` tag in `index.html` will be changed to point to the hashed
  copy.
    - in either case the result is that `index.html` will include the
      entry point _for the previous build_ rather than for the _current_
      build and this can produce broken behavior, in particular because
      this might import _other_ files that are no longer on the disk
      (and also because, you know, if you run a build you expect that
      the build emits code based on the current source code, not the
      source code the last time you ran a build)

Further, if both builds were 1) non-HMR / dev-server builds (i.e. the
result of `stencil build`) then, provided there were no code changes
between build one and build two, a working, inlined build will be the
result. However! If _either_ the first build was an HMR build (i.e. from
`stencil build --dev --watch --serve`) _or_ there was a code change so
the hashed filenames will change then the file that is picked up will
refer to things that don't exist. Not good!

fixes #2687
fixes #4948
closes #2970
alicewriteswrongs added a commit that referenced this issue Oct 27, 2023
This fixes an issue where the `www` build and, in particular, some code
that attempts to inline the entry point for the `www` build into the
`index.html` file that the build outputs, was depending on a file which,
in certain circumstances, would not yet be built. This produced
inconsistency across builds, where the `www` build would pick up and
inline the entry point from the _previous_ build (if the build wasn't
deleted) instead of from the current build.

To go into more detail, prior to this change with the `www` output
target if you did:

```sh
stencil build --dev --watch --serve
```

in a Stencil project and _then_ you ran a build (without deleting
`www/`) like:

```sh
stencil build
```

You'd get a non-working build. Not good!

Why did this happen? We have this function which is called as part of
the `www` build:

https://github.com/ionic-team/stencil/blob/5c4ea3d5354596e5cfb544f91bde7f61de1888b4/src/compiler/html/inline-esm-import.ts#L10-L105

This will basically look for the entry point for the `www` build at
`www/build/project-name.js` and, if it finds it, it will inline that
code in the `index.html` file, reducing the number of JS files that have
to be fetch on page-load by one.

However! Without this change we have a race condition where the lazy
build (which writes the file we're looking for to disk) is not written
until after the `www` build executes. This means that:

- on the first build the entry point is not found, so nothing is inlined
  in the HTML. this produces a working build, but the optimization
  (inlining) is missed.
- on the second build, if `www/` is not deleted then the entry point
  from the _first_ build is found and inlined _or_ if the file is larger
  than a cutoff size then a hashed copy of it will be made and the
  `<script>` tag in `index.html` will be changed to point to the hashed
  copy.
    - in either case the result is that `index.html` will include the
      entry point _for the previous build_ rather than for the _current_
      build and this can produce broken behavior, in particular because
      this might import _other_ files that are no longer on the disk
      (and also because, you know, if you run a build you expect that
      the build emits code based on the current source code, not the
      source code the last time you ran a build)

Further, if both builds were 1) non-HMR / dev-server builds (i.e. the
result of `stencil build`) then, provided there were no code changes
between build one and build two, a working, inlined build will be the
result. However! If _either_ the first build was an HMR build (i.e. from
`stencil build --dev --watch --serve`) _or_ there was a code change so
the hashed filenames will change then the file that is picked up will
refer to things that don't exist. Not good!

fixes #2687
fixes #4948
closes #2970
alicewriteswrongs added a commit that referenced this issue Oct 27, 2023
This fixes an issue where the `www` build and, in particular, some code
that attempts to inline the entry point for the `www` build into the
`index.html` file that the build outputs, was depending on a file which,
in certain circumstances, would not yet be built. This produced
inconsistency across builds, where the `www` build would pick up and
inline the entry point from the _previous_ build (if the build wasn't
deleted) instead of from the current build.

To go into more detail, prior to this change with the `www` output
target if you did:

```sh
stencil build --dev --watch --serve
```

in a Stencil project and _then_ you ran a build (without deleting
`www/`) like:

```sh
stencil build
```

You'd get a non-working build. Not good!

Why did this happen? We have this function which is called as part of
the `www` build:

https://github.com/ionic-team/stencil/blob/5c4ea3d5354596e5cfb544f91bde7f61de1888b4/src/compiler/html/inline-esm-import.ts#L10-L105

This will basically look for the entry point for the `www` build at
`www/build/project-name.js` and, if it finds it, it will inline that
code in the `index.html` file, reducing the number of JS files that have
to be fetch on page-load by one.

However! Without this change we have a race condition where the lazy
build (which writes the file we're looking for to disk) is not written
until after the `www` build executes. This means that:

- on the first build the entry point is not found, so nothing is inlined
  in the HTML. this produces a working build, but the optimization
  (inlining) is missed.
- on the second build, if `www/` is not deleted then the entry point
  from the _first_ build is found and inlined _or_ if the file is larger
  than a cutoff size then a hashed copy of it will be made and the
  `<script>` tag in `index.html` will be changed to point to the hashed
  copy.
    - in either case the result is that `index.html` will include the
      entry point _for the previous build_ rather than for the _current_
      build and this can produce broken behavior, in particular because
      this might import _other_ files that are no longer on the disk
      (and also because, you know, if you run a build you expect that
      the build emits code based on the current source code, not the
      source code the last time you ran a build)

Further, if both builds were 1) non-HMR / dev-server builds (i.e. the
result of `stencil build`) then, provided there were no code changes
between build one and build two, a working, inlined build will be the
result. However! If _either_ the first build was an HMR build (i.e. from
`stencil build --dev --watch --serve`) _or_ there was a code change so
the hashed filenames will change then the file that is picked up will
refer to things that don't exist. Not good!

fixes #2687
fixes #4948
closes #2970
alicewriteswrongs added a commit that referenced this issue Oct 27, 2023
This fixes an issue where the `www` build and, in particular, some code
that attempts to inline the entry point for the `www` build into the
`index.html` file that the build outputs, was depending on a file which,
in certain circumstances, would not yet be built. This produced
inconsistency across builds, where the `www` build would pick up and
inline the entry point from the _previous_ build (if the build wasn't
deleted) instead of from the current build.

To go into more detail, prior to this change with the `www` output
target if you did:

```sh
stencil build --dev --watch --serve
```

in a Stencil project and _then_ you ran a build (without deleting
`www/`) like:

```sh
stencil build
```

You'd get a non-working build. Not good!

Why did this happen? We have this function which is called as part of
the `www` build:

https://github.com/ionic-team/stencil/blob/5c4ea3d5354596e5cfb544f91bde7f61de1888b4/src/compiler/html/inline-esm-import.ts#L10-L105

This will basically look for the entry point for the `www` build at
`www/build/project-name.js` and, if it finds it, it will inline that
code in the `index.html` file, reducing the number of JS files that have
to be fetch on page-load by one.

However! Without this change we have a race condition where the lazy
build (which writes the file we're looking for to disk) is not written
until after the `www` build executes. This means that:

- on the first build the entry point is not found, so nothing is inlined
  in the HTML. this produces a working build, but the optimization
  (inlining) is missed.
- on the second build, if `www/` is not deleted then the entry point
  from the _first_ build is found and inlined _or_ if the file is larger
  than a cutoff size then a hashed copy of it will be made and the
  `<script>` tag in `index.html` will be changed to point to the hashed
  copy.
    - in either case the result is that `index.html` will include the
      entry point _for the previous build_ rather than for the _current_
      build and this can produce broken behavior, in particular because
      this might import _other_ files that are no longer on the disk
      (and also because, you know, if you run a build you expect that
      the build emits code based on the current source code, not the
      source code the last time you ran a build)

Further, if both builds were 1) non-HMR / dev-server builds (i.e. the
result of `stencil build`) then, provided there were no code changes
between build one and build two, a working, inlined build will be the
result. However! If _either_ the first build was an HMR build (i.e. from
`stencil build --dev --watch --serve`) _or_ there was a code change so
the hashed filenames will change then the file that is picked up will
refer to things that don't exist. Not good!

fixes #2687
fixes #4948
closes #2970
github-merge-queue bot pushed a commit that referenced this issue Oct 27, 2023
This fixes an issue where the `www` build and, in particular, some code
that attempts to inline the entry point for the `www` build into the
`index.html` file that the build outputs, was depending on a file which,
in certain circumstances, would not yet be built. This produced
inconsistency across builds, where the `www` build would pick up and
inline the entry point from the _previous_ build (if the build wasn't
deleted) instead of from the current build.

To go into more detail, prior to this change with the `www` output
target if you did:

```sh
stencil build --dev --watch --serve
```

in a Stencil project and _then_ you ran a build (without deleting
`www/`) like:

```sh
stencil build
```

You'd get a non-working build. Not good!

Why did this happen? We have this function which is called as part of
the `www` build:

https://github.com/ionic-team/stencil/blob/5c4ea3d5354596e5cfb544f91bde7f61de1888b4/src/compiler/html/inline-esm-import.ts#L10-L105

This will basically look for the entry point for the `www` build at
`www/build/project-name.js` and, if it finds it, it will inline that
code in the `index.html` file, reducing the number of JS files that have
to be fetch on page-load by one.

However! Without this change we have a race condition where the lazy
build (which writes the file we're looking for to disk) is not written
until after the `www` build executes. This means that:

- on the first build the entry point is not found, so nothing is inlined
  in the HTML. this produces a working build, but the optimization
  (inlining) is missed.
- on the second build, if `www/` is not deleted then the entry point
  from the _first_ build is found and inlined _or_ if the file is larger
  than a cutoff size then a hashed copy of it will be made and the
  `<script>` tag in `index.html` will be changed to point to the hashed
  copy.
    - in either case the result is that `index.html` will include the
      entry point _for the previous build_ rather than for the _current_
      build and this can produce broken behavior, in particular because
      this might import _other_ files that are no longer on the disk
      (and also because, you know, if you run a build you expect that
      the build emits code based on the current source code, not the
      source code the last time you ran a build)

Further, if both builds were 1) non-HMR / dev-server builds (i.e. the
result of `stencil build`) then, provided there were no code changes
between build one and build two, a working, inlined build will be the
result. However! If _either_ the first build was an HMR build (i.e. from
`stencil build --dev --watch --serve`) _or_ there was a code change so
the hashed filenames will change then the file that is picked up will
refer to things that don't exist. Not good!

fixes #2687
fixes #4948
closes #2970
@alicewriteswrongs
Copy link
Contributor

Hey all! I just merged a change (#4992) which I believe will fix this issue. That fix will be included in our next Stencil release, so stay tuned for that! I (or someone else on the team) will ping here when that's ready, so stay tuned 🙂 I'm going to close for now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Needs Investigation This PR or Issue should be investigated from the Stencil team
Projects
None yet
Development

No branches or pull requests