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

Extend vue loaders #732

Closed
yazfield opened this issue Apr 22, 2017 · 10 comments
Closed

Extend vue loaders #732

yazfield opened this issue Apr 22, 2017 · 10 comments

Comments

@yazfield
Copy link

Is there a way to extend vue loaders? I'm trying to use vue-i18n in single file components
this is what i want to achieve

// ...
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            i18n: '@kazupon/vue-i18n-loader'
          }
        }
// ...

Thanks in advance.

@JeffreyWay
Copy link
Collaborator

Not at the moment.

@eminos
Copy link

eminos commented Sep 13, 2017

Has this feature been added yet? Is there a workaround?
I'm trying to do the same thing as the OP.
http://kazupon.github.io/vue-i18n/en/sfc.html

@JBtje
Copy link

JBtje commented Oct 18, 2017

Edit: don't do hack, but use code from next post
After quite a bit of time, I found a hack to make it work. but do note the word hack, since it will alter the laravel-mix code and is thus not future update proof.

Add the line i18n: '@kazupon/vue-i18n-loader', in two places in laravel-mix/src/builder/webpack-rules.js

rules.push({
    test: /\.vue$/,
    loader: 'vue-loader',
    exclude: /bower_components/,
    options: {
        // extractCSS: Config.extractVueStyles,
        loaders: Config.extractVueStyles ? {
            // ...
            i18n: '@kazupon/vue-i18n-loader',
        } : {
            // ...
            i18n: '@kazupon/vue-i18n-loader',
        },
        // ...
    }
});

next: how to do this w/o altering the mix file...

@JBtje
Copy link

JBtje commented Oct 18, 2017

Once you understand how things works, it's just too simple :|...

Just add this to webpack.mix.js

mix.webpackConfig({
    // ...
    module: {
        rules: [
            {
                // Origional @ laravel-mix/src/builder/webpack-rules.js
                // require('webpack-merge').smart() will merge below code with the full configuration, overwriting the
                // default configuration for .vue files in "laravel-mix/src/builder/webpack-rules.js"
                test: /\.vue$/,
                loader: 'vue-loader',
                exclude: /bower_components/,
                options: {
                    // extractCSS: Config.extractVueStyles,
                    loaders: Config.extractVueStyles ? {
                        js: {
                            loader: 'babel-loader',
                            options: Config.babel()
                        },

                        scss: vueExtractPlugin.extract({
                            use: 'css-loader!sass-loader',
                            fallback: 'vue-style-loader'
                        }),

                        sass: vueExtractPlugin.extract({
                            use: 'css-loader!sass-loader?indentedSyntax',
                            fallback: 'vue-style-loader'
                        }),

                        css: vueExtractPlugin.extract({
                            use: 'css-loader',
                            fallback: 'vue-style-loader'
                        }),

                        stylus: vueExtractPlugin.extract({
                            use: 'css-loader!stylus-loader?paths[]=node_modules',
                            fallback: 'vue-style-loader'
                        }),

                        less: vueExtractPlugin.extract({
                            use: 'css-loader!less-loader',
                            fallback: 'vue-style-loader'
                        }),

                        i18n: '@kazupon/vue-i18n-loader',
                    } : {
                        js: {
                            loader: 'babel-loader',
                            options: Config.babel()
                        },

                        i18n: '@kazupon/vue-i18n-loader',
                    },
                    postcss: Config.postCss,
                    preLoaders: Config.vue.preLoaders,
                    postLoaders: Config.vue.postLoaders,
                    esModule: Config.vue.esModule
                }
            },
            // ...
        ]
    },
    // ...
});

@JBtje
Copy link

JBtje commented Apr 13, 2018

With the current version of Laravel-mix, the above code generates the error:
[Vue warn]: Failed to mount component: template or render function not defined.. Unclear however why it does that.

@JeffreyWay I tried multiple approaches to add i18n, using the docs of the latest version of laravel-mix, but all failed with errors. Eventually I forked it and added the lines myself, but that would be a temp. solution.

The docs seem to suggest it is possible to merge new config with the current one, using webpackEntry and/or webpackRules. Perhaps you can add an example here/in the docs?

@ststaynov
Copy link

ststaynov commented Apr 18, 2018

@JBtje It generated that error because vue-loader get's imported twice using that setup. You should use the recently added functionality mix.extend() to define rules

Edit: see #1487

@JBtje
Copy link

JBtje commented Jun 5, 2018

In case anyone comes here searching for the solution:

// The below code will inject i18n Kazupon/vue-18-loader as a loader for .vue files.
mix.extend( 'i18n', function( webpackConfig, ...args ) {
    webpackConfig.module.rules.forEach( ( module ) => {
        if( module.loader !== 'vue-loader' ) 
            return;
        module.options.loaders.i18n = '@kazupon/vue-i18n-loader';
    } );
} );

// We need to inject the vue-18n-loader, before we call .js(..., ...)
mix.i18n()
   .js( 'resources/assets/js/App.js', 'public/js/app.js' )
   .sass( 'resources/assets/scss/app.scss', 'public/css' )
   .version();

@lukadriel7
Copy link

Hello, This topic has been closed for a while now, but with the new version of mix, a lot of things seems to have changed. Can anyone show a new way to add vue-i18n-loader in laravel-mix 4 ?

@JBtje
Copy link

JBtje commented Dec 20, 2018

@lukadriel7 I've been keeping the vue-i18n documentations regarding laravel-mix up to date, so you can find the code in the documentations of vue-i18n:
http://kazupon.github.io/vue-i18n/guide/sfc.html#laravel-mix

@lukadriel7
Copy link

@JBtje Thank you very much, I had done some digging myself and came up with a solution where I simply pushed vue-i18n in the rules array like this

const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.extend( 'i18n', function( webpackConfig, ...args ) {
    webpackConfig.module.rules.push(
        {
            resourceQuery: /blockType=i18n/,
            type: 'javascript/auto',
            loader: '@kazupon/vue-i18n-loader',
        }
    )
} );

mix.i18n().js('resources/js/app.js', 'public/js')
   .sass('resources/sass/app.scss', 'public/css');

But I guess it would be better to go with your solution.
Thank you again

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

No branches or pull requests

6 participants