Webpack-encore: Import Components from vue does not work

Created on 30 Nov 2018  路  14Comments  路  Source: symfony/webpack-encore

Hi everyone,

I'm sorry in advance because i'm not sure that this issue has it place here.

I'm using vue in my Symfony project using webpack-encore's config. My webpack config is really basic and it works but, the problem is in my main.ts, i would like to import a component (Header.vue that is in ./test/Header.vue).

  • When i'm using the import statement -> import Header from "./test/Header.vue", it doesn't work and return that cannot find the module.
  • When i'm using require statement -> const Header = require('./test/Header.vue').default it works

It seems like webpack-encore babel's configuration does not read ES2015 statement ( and i really want to use it );

My question is, how can i configure babel (if the problem comes from it) to make the import statement works ?

Thanks !

// main.ts
import Vue from 'vue'; // Here it work
import store from './store'; // Here too

// import Header from "./test/Header.vue"; // But here not :'(
// const Header = require('./test/Header.vue').default;

 // Vue.component("test", Header);

new Vue({
    store,
    delimiters: ["%%", "%%"],
}).$mount('#app');

require('./styles/main.scss');
HasPR bug

Most helpful comment

What's inside your webpack.config.js?
Do you have a config file for Babel or TypeScript?
Is it Babel or tsc that is used to parse .ts files?

Maybe you need to declare a shim file like this:

// shims-vue.d.ts
declare module '*.vue' {
  import Vue from 'vue';
  export default Vue;
}

and configure tsc to include it

All 14 comments

Hi @RomainoSoko!

Hmm, indeed - this is not the expected behavior, and Babel IS configured to understand the import statements just fine. What does your Header.vue file look like?

Cheers!

Plop !

Thanks @weaverryan for your interest to this post, there is my Header.vue file :

// Header.vue

<template>

</template>

<script lang="ts">
    import {
        Vue,
        Component,
        Watch,
        Prop
    } from "vue-property-decorator";
    @Component
    export default class Header extends Vue {
        public mounted() {
            console.log('test');
        }
    }
</script>

I've done some research and I still have no idea where it might come from.

Hope that this can help you.

Thanks again !

What's inside your webpack.config.js?
Do you have a config file for Babel or TypeScript?
Is it Babel or tsc that is used to parse .ts files?

Maybe you need to declare a shim file like this:

// shims-vue.d.ts
declare module '*.vue' {
  import Vue from 'vue';
  export default Vue;
}

and configure tsc to include it

@Kocal There is my webpack config :

//webpack.config.fr
const Encore = require('@symfony/webpack-encore');
const path = require('path');
Encore
    .setOutputPath('public/build/')
    .setPublicPath('/build')
    .addEntry('app', './src/main.ts')
    .enableSingleRuntimeChunk()

    .cleanupOutputBeforeBuild()
    .enableBuildNotifications()
    .enableSourceMaps(!Encore.isProduction())

    .enableVersioning(Encore.isProduction())

    .enableSassLoader(function(options) {}, {
        resolveUrlLoader: false
    })
    .enableVueLoader()
    .enablePostCssLoader()

    .enableTypeScriptLoader()
    .enableForkedTypeScriptTypesChecking()
;
    const config = Encore.getWebpackConfig();
    config.resolve = {
    extensions: ['.js', '.ts', '.vue', '.tsx'],
    alias: {
        '@src': path.resolve(__dirname, './src/')
    }
};


module.exports = config;

Hum, normally in a raw webpack configuration, you should pass appendTsSuffixTo: [/\.vue$/] options to the ts-loader if you want to use Vue and TypeScript, but I didn't see it in webpack-encore source code.

What happens if you use

Encore.enableTypeScriptLoader({
  appendTsSuffixTo: [/\.vue$/]
})

Any updates on this? ping @RomainoSoko

Yes ! sorry, was on hollyday :)

Then, I've tried it and it doesn't work, telling that "Argument 1 to enableTypeScriptLoader() must be a callback function". I've tried many other solutions, but nothing does about it :/

Don't worry, I was in hollyday too :p

Ah, I tought it was possible to pass a plain object. :thinking:

What about this?:

Encore.enableTypeScriptLoader((options) => {
  options.appendTsSuffixTo = [/\.vue$/]
})

This is good because webpack doesn't return any error (it can read it), but the class import in my main.ts still don't work..

I also need to specify that imports work for the node_modules, the problem really comes from the classes import

Nice.

By the way, what is inside your tsconfig.json?

There is my tsconfig.json, using recommended configuration from Vue :).

//tsconfig.json

{
  "compilerOptions": {
    "moduleResolution": "node",
    "module": "es2015",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true,
    "target": "es5",
    "lib": [
      "esnext",
      "dom"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
  ],
  "exclude": [
    "node_modules"
  ]
}

Hum, normally you don't need to have "src/**/*.vue" :thinking:
At least, I'd never use it in my projects

Hi there,

Setting the appendTsSuffixTo option of the ts-loader should indeed be enough to solve that issue (see this repository that contains a small example).

I created a PR to add it automatically when needed (#484).

Wonderful! :tada:

So I guess the main issue here is include: ["src/**/*.vue"] from his tsconfig.json

Was this page helpful?
0 / 5 - 0 ratings