teatimes
teatimes

Reputation: 1

Run backend (Elixir) and frontend (Angular 8) together

I have created an application with Elixir and Phoenix backend, and Angular 8 frontend, connected trough a REST API. Originally, I run them separate (mix phx.server and ng serve as separate commands), but I thought it would be easier to run them together, both in development and production. I have done so with previous Elixir applications with Elm frontend, where I only have to run mix phx.server to start backend and frontend.

I use webpack, and I know it bundles the main.ts file into main.js. But, when I then start the application, it sends get requests for all the html files, e.g. localhost:4000/app.component.html.

In the example I tried to follow (https://github.com/akeating/peap), it imported runtime.js, vendor.js and style.js in the html file. I haven't figured out how to create them when not running ng serve directly, so at the moment I include them in webpack based on the dist files created previously (which I assume isn't optimal or correct). Run backend (Elixir) and frontend (Angular 8) together - Stack Overflow

My webpack config looks like this:

const path = require('path');
const glob = require('glob');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
//const ProvidePlugin = require('provide-plugin');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

const mainPath = path.resolve('angular', 'src', 'app')
const mainEntryFile = path.join(mainPath, 'main.ts')

const HtmlWebpackPlugin = require("html-webpack-plugin")
const helpers = require('./helpers')

module.exports = (env, options) => ({
  optimization: {
    minimizer: [
      new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }),
      new OptimizeCSSAssetsPlugin({})
    ]
  },
  entry: {
    main: './angular/src/main.ts',
    runtime: './angular/dist/<app-name>/runtime.js',
    vendor: './angular/dist/<app-name>/vendor.js',
    styles: './angular/dist/<app-name>/styles.js'
    //'./js/app.js': './src/main.ts'
    //'./js/app.js': glob.sync('./vendor/**/*.js').concat(['./js/app.js'])
  },
  output: {
    filename: 'js/[name].js',
    path: path.resolve(__dirname, '../priv/static')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      //{ test: /[\/\\]@angular[\/\\].+\.js$/, parser: { system: true } },
      {
        test: /\.ts?$/,
        exclude: /node_modules/,
        loaders: [
          {
            loader: 'awesome-typescript-loader',
            options: { configFileName: './angular/tsconfig.json',
            cwd: path.resolve(__dirname, 'angular', 'src')}
          },
        ]
      },
      { test: /.(png|woff(2)?|eot|ttf|svg)(\?[a-z0-9=\.]+)?$/, loader: 'url-loader?limit=100000' },
      { test: /\.html$/, loaders: ['raw-loader'] },
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          {loader: 'css-loader', options: { minimize: true } }
        ]
      },
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'less-loader',
         ]
      },
    ],
  },
  resolve: {
    extensions: ['.ts', '.js'],
    alias: {}
  },
  plugins: [
    new MiniCssExtractPlugin({ filename: '../css/app.css' }),
    new CopyWebpackPlugin([{ from: 'static/', to: '../' }]),
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery'
    }),
    new webpack.ContextReplacementPlugin(
        /\@angular(\\|\/)core(\\|\/)fesm5/,
        helpers.root('./src')
    ),
    new CleanWebpackPlugin({
       dry: true,
     })
    //new webpack.NoEmitOnErrorsPlugin()
  ]
});

Any help or pointers in the right direction would be really appreciated.

Upvotes: 0

Views: 557

Answers (1)

Haseeb A
Haseeb A

Reputation: 6152

May be its because the code you are trying to follow is very old. Current version of phoenix by default uses webpack for mananging js dependancies. So any webpack configuration will work without any changes. The default setting is to run webpack server along when you are running phoenix server. So don't change anything in phoenix side. Go ahead and move your angular application to /assets with webpack configuration on the same folder. It will simply work

Upvotes: 0

Related Questions