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

Async Webcomponents can not be loaded from other directory than ./ #949

Closed
batje opened this issue Mar 6, 2018 · 8 comments
Closed

Async Webcomponents can not be loaded from other directory than ./ #949

batje opened this issue Mar 6, 2018 · 8 comments
Labels

Comments

@batje
Copy link

batje commented Mar 6, 2018

Version

3.0.0-beta.5

Reproduction link

https://github.com/batje/asyncwcpath

Steps to reproduce

  • Compile at least 2 components with --target wc-async
  • copy dist/demo.html to src/demo.html
  • in src/demo.html change the path to your component.js by adding ../dist/
  • load src/demo.html in your browser.
  • component.js will load, but component.1.js will fail

What is expected?

component.1.js should be loaded from a path relative to component.js, not relative to the demo.html file.

What is actually happening?

This line

sets publicpath to './' which causes webpack to look for the second file relative to the html file, not the .js file.


Better would be to

  • default to './'
  • add a new command-prompt option called 'libpath' that you can set to a path like the examples in the webpack documentation
  • if 'libpath' equals 'RUNTIME' do not fill in publicpath and allow setting the variable at runtime. eg: webpack_public_path = myRuntimePublicPath

Documentation for this option is here:
https://webpack.js.org/configuration/output/#output-publicpath

@batje
Copy link
Author

batje commented Mar 6, 2018

Awesome

@xavsio4
Copy link

xavsio4 commented Oct 26, 2018

Hi, As I just ran in this very same issue using cli 3, what should then be set in the config file to actually make components files relate to the main js file and not demo.html ? I've tried to put the above in the config file but with no luck. (vue v3.0.5) with command "vue-cli-service build --dest ../frontend/web/vuejs --target wc-async --name app-vue 'src/components/*.vue'". Components are still not found because it is still looking in the root and not relatively to the main js file. In fact, I don't want to use demo.html. i would like to use a file outside the vuejs folder.
Thanks for your input (hoping this is the right place to raise my question)

@batje
Copy link
Author

batje commented Oct 26, 2018

Not sure if I understand correctly. The issue I describe is fixed.
Basically, webcomponents run completely independent. You only need to include vue, and the webcomponents js file. After that, there is no js code in your html anymore, only you custom <component> tags.

The issue was, you could not do that with 2 vue based webcomponents on the same page. Now you can.

@xavsio4
Copy link

xavsio4 commented Oct 26, 2018

Well, still that is what I exactly did, the files are generated in the "..frontend/web/vuejs/" folder in a remote php project . The calling page in the root of that project has the vuejs and main component called, in my case, app-vue.min.js is the main component. In my webpage i'm using the tags (just as it is done on the demo.html file) and in the console i get this error "GET http://localhost/yiivue/frontend/web/app-vue.3.min.js net::ERR_ABORTED 404 (Not Found)" so the components are not loaded with the path relative to the main component which is called in "http://localhost/yiivue/frontend/web/vuejs/" but relative to the calling webpage. Now, if I move the components files where the calling page is, everything works fine. In that case, the main generated file is still in the folder "/vuejs" but the generated files components are in the root folder along with the calling page. I've tried to force that with a vue.config.js file by using this piece of codemodule.exports = { baseUrl: '/vuejs/', };
And run the build command again, but I can't see no changes. Surely, I'm doing something wrong but can't figure out what (All is done on Chrome).

@batje
Copy link
Author

batje commented Oct 26, 2018

Every component creates a set of files for that component. There is no main.js, because there is no Vue project. And all component files have to be in the same folder.

here is a sample component, which is the only vue file I have in my sample project:

<template>
  <div>
    ComponentOne
  </div>
</template>

<script>
export default {
  name: 'ComponentOne',
  props: {
    msg: String
  }
}
</script>

If you compile that file with:

vue-cli-service build --target wc-async 'src/components/*.vue'

You get a set of .js files in the /dist folder. These files need to stay in the same folder. In your html header you include:

    <script src="component1/node_modules/vue/dist/vue.js"></script>
    <script src="component1/dist/component-one.js"></script>

and now you can use your new tag:

<component-one></component-one>

@xavsio4
Copy link

xavsio4 commented Oct 26, 2018

Ok, then what I was thinking about might then not be possible. In the documentation I read that when you have a large app with a lot of components you could use wc-async to split those components (foo-1, foo2, foo3, ....) and that only the component which is going to be used is going to be loaded on the page. Also I understood (badly it seems) that you only have to load the main vue component (which calls other components) and you don't have to link all generated js files in your page (and that is working if all files, including the page, are in the same folder. This is my "hub" component

<template>
  <div id="app">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
    <ArticleList></ArticleList>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import ArticleList from './components/ArticleList.vue'

export default {
  name: 'app',
  components: {
    HelloWorld,
    ArticleList
  }
}
</script>

and so the wc-async generates (with my command) app-vue.js, app-vue.1.js, app-vue.2.js, etc...
but i only link app-vue.js in the page. just like the demo one

<meta charset="utf-8">
<title>app-vue demo</title>
<script src="https://unpkg.com/vue"></script>
<script src="./app-vue.js"></script>
<app-vue-article-list></app-vue-article-list>
<app-vue-hello-world></app-vue-hello-world>

What i did wanted anyway is something like this

<meta charset="utf-8">
<title>app-vue demo</title>
<script src="https://unpkg.com/vue"></script>
<script src="**vuejs/app-vue.js**"></script>

<app-vue-article-list></app-vue-article-list>

<app-vue-hello-world></app-vue-hello-world> 

from a page outside the generated js folder. But that won't work because there is not path for the components app-vue.1 and so on. That would have been nice, for example, to have a generation where demo.html is not in the same folder as the generated components. But perhaps I handle this problem from the wrong side.

@batje
Copy link
Author

batje commented Oct 26, 2018

You dont need a hub component, the compile statement compiles all components in the components folder into your dist/ folder and creates 1 entry .js file

vue-cli-service build --target wc-async 'src/components/*.vue' --name=mycomponents

Now there will be 1 js file called dist/mycomponents.js Include that file, and you have access to all your components like <mycomponents-name1> etc. No hub needed.

@bjunc
Copy link

bjunc commented Apr 17, 2021

Is there a way to explicitly set the public path? This "fix" makes a few assumptions that the file will end with .js, and that the async files will be relative to the current script. This does not work for our use-case; which is to create a proxy to web components (a la Docker versioning).

For instance:

https://libs.example.com/wc:latest would proxy/redirect to https://some-cdn.com/webcomponents/v1.23.4/wc.min.js

Under the current config, this will break. A workaround is to do something like this:

https://libs.example.com/wc/latest/lib.js

This is pretty ugly, IMO. It'd be better to be able to have an escape hatch to explicitly set the public path.

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

No branches or pull requests

4 participants