CroudTech / vue-fullcalendar

FullCalendar Wrapper for vue
MIT License
483 stars 100 forks source link

Cannot Build Project with Full Calendar #112

Open MackAttack26 opened 6 years ago

MackAttack26 commented 6 years ago

Can somebody please help me with this issue of building full calendar. I have attached a screen shot of the error and my package.json file. I followed the instructions accordingly.

The error essentially says

ERROR in ./~/vue-full-calendar/components/FullCalendar.vue Module parse failed: C:\Users\shaun\Documents\Projects\Branch\Trunk - Full Caldendar v2----\node_modules\vue-full-calendar\components\FullCalendar.vue Unexpected token (1:0) You may need an appropriate loader to handle this file type. | @ ./~/vue-full-calendar/index.js 1:0-56 @ ./ClientApp/app.js @ ./ClientApp/boot-app.js

full calendar package json

full calendar build error full calendar webpack config

BrockReece commented 6 years ago

Hey @MackAttack26,

What does you webpack config look like, at first glance it looks as though your vue-loader maybe excluding files from your node_modules directory?

MackAttack26 commented 6 years ago

@BrockReece

I updated the original post to include the WebPack configuration file. Thanks for your help.

BrockReece commented 6 years ago

It looks like line 32 has an include option, this will effectively exclude transpiling any '.vue' files outside of '/ClientApp/'. I'm guessing your node_modules dir and therefore this lib lives outside of '/ClientApp/'

MackAttack26 commented 6 years ago

I updated the WebPack config file to include the reference to the node_module folder which is outside of the ClientApp folder, but no dice. I'm fairly new to Vue and WebPack configurations so I may not have added the reference correctly.

updated webpack

BrockReece commented 6 years ago

Hi @MackAttack26 Sorry for the delay.

So the include condition can be structured as array of paths to include, you should be able to refactor both of those rules into one.

{
  test: /\.vue$/,
  include: [
    '/ClientApp/',
    'relative/path/to/node_modules/',
  ],
  use: 'vue-loader',
}

See these docs for more info.

FWIW, Webpack doesn't require you to have an include condition. You can remove this condition and then Webpack will transpile every .vue file in your project.

Hope that helps?

MackAttack26 commented 6 years ago

Hi @BrockReece,

I really do appreciate your help with this. I'm still getting the same error and here is my updated WebPack config. When it is building, it is failing on the "~\node_modules\vue-full-calendar\components\FullCalendar.vue" file which to me, in my limited knowledge, indicates that it is able to find the file, and attempts to include it in the packaging, but has an issue with the component in the file. I also tried using the component locally with no luck for the same error. Just for some background, I've imported many libraries into our project before, and haven't had an issue. Before attempting to use Full Calendar, the project was building and running successfully. Any other thoughts as to why it doesn't like this component?

updated webpack vue error

BrockReece commented 6 years ago

Hi @MackAttack26

Sorry for the delay, it has been a busy week. Did you try removing the include statement completely as I suggested in an earlier comment?

MackAttack26 commented 6 years ago

No problem. I did try that and it led to almost every vue component in my project having the same error. So i've now tried only having my "ClientApp" included, "ClientApp" and "node_modules/vue-full-calendar" included and they all give me the same error. I've tried "ClientApp" and "node_modules", and "no includes" at all and it gives me errors on almost all of my vue's. I'm including my project layout to show that node_modules is at the same level as ClientApp.

vue project layout

j-fdion commented 6 years ago

Does anyone have found a solution for this, I've got the same problem.

Edit: Found a way to circumvent this problem, I placed FullCalendar.vue in my ClientApp/Components directory and I imported it as a component:

import FullCalendar from './FullCalendar'
Vue.component('full-calendar', FullCalendar);

I do think the problem comes from the webpack configuration but I don't know how to correct it...

steven87vt commented 6 years ago

Hello,

This issue is still open so I am posting here to hopefully help anyone else that runs across this issue. I picked this issue up for @MackAttack26 today (e.g. we work together) and I solved this issue one of three ways:

  1. Removing the includes section of the vue loader as @BrockReece mentioned rules: [{ test: /\.vue$/, use: 'vue-loader'}...]
  2. Including a path.resolve instruction locating the vue-full-calendar directory. rules: [{ test: /\.vue$/, include: [/ClientApp/, path.resolve(__dirname, 'node_modules/vue-full-calendar'),],use: 'vue-loader'}...]
  3. Including a simple path of /node_modules/ rules: [{ test: /\.vue$/, include: [/ClientApp/, /node_modules/),],use: 'vue-loader'}...]

Trying to isolate this directory using a simple regex described in @MackAttack26 last comment would fail (e.g. /node_modules\/vue-full-calendar) even though it appears to find the path.

All I had to do was follow the instructions given on the readme page and as soon as you import FullCalendar it fails to find load the vue component. Not sure why and to @MackAttack26's point we have multiple vue components loaded simply by adding them to the project package.json dependencies and calling import Component from 'vue-component' and isolating the vue-loader defined in webpack.config.js to our ClientApp directory

BrockReece commented 6 years ago

Hello @steven87vt @MackAttack26 @j-fdion Sorry for the delay again.

Thanks for your messages and I am glad to hear that my webpack advice ultimately did work. Though I do share @MackAttack26 's concern that this package isn't behaving in the same way as other third party Vue components, could you tell me a couple of your other third party dependencies so I can compare notes on how to bundle my project up?

For reference, this was built and tested with the https://github.com/vuejs-templates/webpack generator which has no include key in their webpack config, I considered this to be the most typical build configuration. Can I ask whether you generated your application or built it by hand?

Once again sorry for the delay, and I really do want to help resolve this.

steven87vt commented 6 years ago

Hello @BrockReece

Thank you for your help! Full disclosure I am new to vue.js so I am probably not the best person to answer this but here it goes. Looking for something that follows the same style of template implementation as this library I would point to vue-highcharts and vue-form-wizard as something we use in a similar fashion.

The below example compares the these two libraries implemented in different ways, one used inside our component.vue and the other at the app level.

package.json: "dependencies": { ... "vue-form-wizard": "^0.8.4", "vue-highcharts": "0.0.10" ...

webpack.config.js (original):

const path = require('path')
const webpack = require('webpack')
const bundleOutputDir = './wwwroot/dist'
const CopyWebpackPlugin = require('copy-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const WorkboxPlugin = require('workbox-webpack-plugin')

module.exports = (env) => {
const isDevBuild = !(process.env.NODE_ENV && process.env.NODE_ENV === 'production')

return [{
    stats: { modules: false },
    entry: { 'main': './ClientApp/boot-app.js' },
    resolve: {
        extensions: ['.js', '.vue'],
        alias: {
            'vue$': 'vue/dist/vue',
            'components': path.resolve(__dirname, './ClientApp/components'),
            'views': path.resolve(__dirname, './ClientApp/views'),
            'utils': path.resolve(__dirname, './ClientApp/utils'),
            'api': path.resolve(__dirname, './ClientApp/store/api')
        }
    },
    watchOptions: {
        aggregateTimeout: 300,
        poll: 1000
    },
    output: {
        path: path.join(__dirname, bundleOutputDir),
        filename: '[name].js',
        publicPath: '/'
    },
    module: {
        rules: [
            { test: /\.vue$/, include: /ClientApp/, use: 'vue-loader' },
            { test: /\.js$/, include: /ClientApp/, use: 'babel-loader' },
            { test: /\.css$/, use: isDevBuild ? ['style-loader', 'css-loader'] : ExtractTextPlugin.extract({ use: 'css-loader' }) },
            { test: /\.(eot|woff|woff2|ttf|svg|png|jpe?g|gif)(\?\S*)?$/, use: 'url-loader?limit=100000&name=[name].[ext]'}]
    },
    plugins: [
        new CopyWebpackPlugin([{
            from: './ClientApp/images'
        }]),
        new webpack.DllReferencePlugin({
            context: __dirname,
            manifest: require('./wwwroot/dist/vendor-manifest.json')
        }),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': isDevBuild ? '"development"' : '"production"'
        }),
        new HtmlWebpackPlugin({
            title: 'MyTitle',
            template: 'ClientApp/templates/index.template.ejs'
        }),
        new webpack.SourceMapDevToolPlugin({
            filename: '[file].map',
            // Point sourcemap entries to the original file locations on disk
            moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]')
       })
    ]
}];

};

boot-app.js:

import 'core-js/es6/promise'
import 'core-js/es6/array'
import { app } from './app'
app.$mount('#app')

app.js:

import Vue from 'vue'
import VueFormWizard from 'vue-form-wizard'
...
Vue.use(VueFormWizard);

some-component.vue:

<template>
    ...
    <form-wizard ref="formWizard"
        @on-complete="onComplete"
        :finishButtonText="buttonText"
        shape="tab"
        color="#004566">
        <tab-content title="Describe" :before-change="beforeDescriptionSwitch">
    ...
</template>
<script>
    import { FormWizard, TabContent } from 'vue-form-wizard'
    export default {
            name: "some-name",
            components: {
                FormWizard,
                TabContent
            }
            ...
    },
</script>

some-other-component.vue:

<template>
    ...
        <highcharts :options="options" ref="highcharts" ...></highcharts>
    ...
</template>
<script>
    ...
    import VueHighcharts from 'vue-highcharts';
    ...
</script>
BrockReece commented 6 years ago

QQ, Is this using Laravel/Lumen?

BrockReece commented 6 years ago

So the reason that these libs work is that they have already compiled their SFC's down to browser ready JS. Where as in my lib, you are importing the raw .vue components.

steven87vt commented 6 years ago

Awesome, at least now we know. Thanks again for your help!

BrockReece commented 6 years ago

@MackAttack26 @j-fdion @steven87vt

I have created a new branch with a pre transpiled build, as per the 2 libs listed above. Could you test this new version for me and let me know how you get on?

npm install vue-full-calendar@bili
davbtmx commented 6 years ago

I was not able to build for production with webpack, because uglifyjs can only process ES5 and libraries in /node_modules are not transpiled to ES5 by babel, so the ES6 .vue component could not be processed by uglifyjs and generated an error. Testing the @bili branch and its ES5 version of vue-full-calendar in the /dist directory, everything works fine.

steven87vt commented 6 years ago

@davbtmx I am using this just fine with babel, uglify and webpack in multiple domains.

"devDependencies": {
        "babel-core": "^6.26.3",
        "babel-loader": "^6.2.10",
        "babel-plugin-transform-async-to-generator": "^6.22.0",
        "babel-plugin-transform-runtime": "^6.22.0",
        "babel-preset-env": "~1.7.0",
        "babel-preset-stage-2": "~6.24.1",
        "babel-preset-stage-3": "~6.24.1",
        "uglifyjs-webpack-plugin": "^1.2.5",
    }

.bablerc, comments taken directly from babel website.

{
    "presets": [
        [
            "env",
            {
                "development": {
                    "targets": {
                        "browsers": [
                            "last 2 Chrome versions",
                            "last 2 Firefox versions",
                            "last 2 Edge versions",
                            "last 2 Opera versions",
                            "last 2 Safari versions",
                            "ie 11"
                        ]
                    },
                    "debug":  true
                },
                "production": {
                    "browsers": [
                        "last 2 Chrome versions",
                        "last 2 Firefox versions",
                        "last 2 Edge versions",
                        "last 2 Opera versions",
                        "last 2 Safari versions",
                        "ie 11"
                    ]
                }
            }
        ]
    ],
    "plugins": [
        "transform-runtime",
        "transform-async-to-generator",
        //stage 2 plugins must be declared manually because preset-env does not include them by default and will not accept stage-2 as an option.
        "syntax-dynamic-import",
        "transform-class-properties",
        "transform-decorators",
        //stage 3 plugins must be declared manually because preset-env does not include them by default and will not accept stage-2 as an option.
        "transform-object-rest-spread",
        "transform-async-generator-functions",
        "syntax-trailing-function-commas", //trailing-commas, async, exponentiation will be removed in the next major since they are stage 4 already
        "transform-async-to-generator",
        "transform-exponentiation-operator"
    ],
    ...
}