Home > Mobile >  Building an AngularJS and Vue.js into one app using webpack?
Building an AngularJS and Vue.js into one app using webpack?

Time:10-31

This may seem a bit convoluted, and potentially the answer is "don't do it that way, do it this way" so I'll start with the background of what I am doing. Basically I have a legacy AngularJS app that we want to migrate away from and towards Vue. We do not have the option to end-to-end rewrite the app, and need to do it piece by piece whilst still delivering a functional app.

The general goal is to therefore have both frameworks running simultaneously, my hope is that I can either do something with the routing or potentially split my single page app into 2 seperate pages for the different fraweworks. I have converted the angularjs from using a gulp build pipeline to using webpack as I assumed this was a logical first step to getting Vue to run, but now I have hit a road block.

My working webpack.config.js for building the angular app looks like the following:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    target: 'web',
    // mode: "development",
    // devtool: "source-map",
    module: {
        rules: [

            {
                test: /\.html$/,
                loader: "html-loader",
            },
            {
                test: /\.s[ac]ss$/i,
                use: [
                  "style-loader",
                  "css-loader",
                  "sass-loader",
                ],
              },
              {
                test: require.resolve("jquery"),
                loader: "expose-loader",
                options: {
                  exposes: ["$", "jQuery"],
                },
              }
        ],
    },
    entry: {
        vendor: "./source/vendor.js",
        main: "./source/index.js",
    },
    optimization: {
        minimize: false
    },
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'distribution'),
        clean:true
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'source/index.html',
        })
    ]
};

this now works fine and I get something out add the end that works as it did before.

I then added a /source/vueJs directory, and copy & pasted the content hello world project that is generated by vue create hello-world. My assumption was if I could modify my webpack.config.js to build this, I could then iterate on it further to get to a point where it merged the two working apps together, but I'm already struggling to get the hello-world vue project to produce anything.

So far I basically commented out all the relevant angularJS parts, and added what I thought was correct to get the vue app to build, so now I have this:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
    target: 'web',
    mode: "development",
    devtool: "source-map",
    module: {
        rules: [

            // {
            //     test: /\.html$/,
            //     loader: "html-loader",
            // },
            // {
            //     test: /\.s[ac]ss$/i,
            //     use: [
            //       "style-loader",
            //       "css-loader",
            //       "sass-loader",
            //     ],
            //   },
            //   {
            //     test: require.resolve("jquery"),
            //     loader: "expose-loader",
            //     options: {
            //       exposes: ["$", "jQuery"],
            //     },
            //   },
            {
                test: /\.(png|jpe?g|gif)$/i,
                use: [
                  {
                    loader: 'file-loader',
                  },
                ],
              },
              {
                test: /\.vue$/,
                loader: 'vue-loader'
              },
              // this will apply to both plain `.js` files
              // AND `<script>` blocks in `.vue` files
              {
                test: /\.js$/,
                loader: 'babel-loader'
              },
              // this will apply to both plain `.css` files
              // AND `<style>` blocks in `.vue` files
              {
                test: /\.css$/,
                use: [
                  'vue-style-loader',
                  'css-loader'
                ]
              }
        ],
    },
    entry: {
        // vendor: "./source/vendor.js",
        // angular: "./source/index.js",
        vue: "./source/vueJs/index.js"
    },
    optimization: {
        minimize: false
    },
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'distribution'),
        clean:true
    },
    plugins: [
        new HtmlWebpackPlugin({
            //template: 'source/index.html',
        }),
        new VueLoaderPlugin()
    ],
};

this runs fine and I get a distribution/ directory with my assets in, but the served site runs as if there is no javascript running at all. Comparing the output of npx webpack on my version and the output of npx vue-cli-service build on the hello-world project, the javascript is similar but different in a lot of key areas, for a start it seems as though my version does not have any HTML embedded in it like the hello world project does.

Is it a lost cause trying to compile a vue app from webpack? Can you only do it using vue-cli-service build and therefore limited to vue only? I tried modifying my vue.config.js using the info found at https://cli.vuejs.org/guide/webpack.html & https://cli.vuejs.org/config/, but frankly I feel I am out of my depth at this point and unsure if what I am doing is even a good idea.

Is there a better strategy to take to get to my end goal? If this is a workable solution, what do I need to change about my configs to get both the angularjs and the vue app to build properly?

CodePudding user response:

I wasn't seeing the wood for the trees. The problem isn't that that webpack.config.js doesn't succesfully producing a working angular & vue combined app, the problem is that I'm not providing a template that actually uses either of these things, so it just produces a blank index.html with the scripts provided but no content in the body.

Changing the

new HtmlWebpackPlugin({
        //template: 'source/index.html',
    }),

in my question to have a template that uses both an AnularJS component and a Vue component worked fine.

  • Related