Skip to content

Guide for the initial configuration for projects that are built with the following technologies stack: Phoenix Framework, Webpack Module Bundler, React Library and GraphQL Query Language and how each element should be organized in the internal structure of the project.

Notifications You must be signed in to change notification settings

nuu-engineering/S1-Project-Setup-and-Structure-Guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NUU Setup and Structure Guide: Phoenix Framework, Webpack Module Bundler, React Library & GraphQL Query Language

Guide for the initial configuration for projects that are built with the following technologies stack: Phoenix Framework, Webpack Module Bundler, React Library and GraphQL Query Language and how each element should be organized in the internal structure of the project.

NUU Group Documents

Table of Contents

Initial Setup

Installation Instructions

To be able to create projects with this stack of technologies it is necessary to install Phoenix on the system. Webpack, React and QraphQL will be installed later on each project when configuring it.

To know if Phoenix has already been installed on the computer, you can enter the following console command:

mix phx.new --version

If this does not return version information, it must have to be installed. In the Phoenix documentation there is a page with the Installation instructions.

Configuration

  1. Create a new Phoenix project:

    mix phx.new project_name

    During the process of creating files, is asked if you want to extract and install the dependencies for the project, indicate yes.

  2. Access to the project_name\assets directory of the project.

    cd project_name\assets
  3. Uninstall via NPM the following dependencies:

    • brunch
    • babel-brunch
    • clean-css-brunch
    • uglify-js-brunch
    npm uninstall --save-dev babel-brunch brunch clean-css-brunch uglify-js-brunch
  4. Delete the brunch-config.js file.

    rm brunch-config.js
  5. Install via NPM the following dependencies:

    • webpack
    • webpack-cli
    • copy-webpack-plugin
    • uglifyjs-webpack-plugin
    • graphql
    • react
    • react-dom
    • react-router-dom
    • prop-types
    • @babel/core
    • @babel/cli
    • @babel/preset-env
    • @babel/preset-react
    • @babel/plugin-proposal-class-properties
    • babel-loader
    • css-loader
    • url-loader
    • file-loader
    • mini-css-extract-plugin
    • optimize-css-assets-webpack-plugin
    npm install --save-dev webpack webpack-cli copy-webpack-plugin uglifyjs-webpack-plugin graphql react react-dom react-router-dom prop-types @babel/core @babel/cli @babel/preset-env @babel/preset-react @babel/plugin-proposal-class-properties babel-loader css-loader url-loader file-loader mini-css-extract-plugin optimize-css-assets-webpack-plugin
  6. Create a new file with .babelrc as file name.

    touch .babelrc
  7. Edit the .babelrc file and place the following code:

    {
      "presets": [
          ["@babel/preset-env", {"modules" : false}],
          "@babel/preset-react"
        ],
      "plugins": [
          "@babel/plugin-proposal-class-properties"
        ]
    }
  8. Edit the package.json file and replace the value of the scripts key with the following code:

    "scripts": {
        "deploy": "webpack --mode production",
        "start": "webpack --mode development --watch-stdin --color"
      },
  9. Create a new file with webpack.config.js as file name.

    touch webpack.config.js
  10. Edit the webpack.config.js file and place the following code:

    const path = require('path');
    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');
    
    module.exports = (env, options) => ({
      optimization: {
        minimizer: [
          new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }),
          new OptimizeCSSAssetsPlugin({})
        ]
      },
      entry: './js/app.js',
      output: {
        filename: 'app.js',
        path: path.resolve(__dirname, '../priv/static/js')
      },
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
              loader: 'babel-loader'
            }
          },
          {
            test: /\.css$/,
            use: [MiniCssExtractPlugin.loader, 'css-loader']
          },
          {
            test: /\.svg$/,
            use: [
              {
                loader: 'file-loader',
                options: {
                  mimetype: 'image/svg+xml',
                  outputPath: '../images',
                  name (file) {
                    if (env === 'development' || env === undefined)
                      return '[name].[ext]'
                    else
                      return '[hash].[ext]'
                  }
                }
              }
            ]
          }
        ]
      },
      plugins: [
        new MiniCssExtractPlugin({ filename: '../css/app.css' }),
        new CopyWebpackPlugin([{ from: 'static/', to: '../' }])
      ]
    });
  11. Access to the project_name\assets\js directory of the project.

    cd js
  12. Create a new file with index.js as file name.

    touch index.js
  13. Edit the index.js file and place the following code:

    // Dependencies
    import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    
    class App extends Component {
      render() {
        return (
          <div>Ok</div>
        );
      }
    }
    
    ReactDOM.render(
      <App />,
      document.getElementById('root')
    );
  14. Create the components, pages and data directories.

    mkdir components && mkdir pages && mkdir data
  15. Edit the app.js file and after the last import place the following code:

    import css from "../css/app.css"
    import { index } from "./index"
  16. Access to the project_name\config directory of the project.

    cd ..\..\config
  17. Edit the dev.exs file and replace the value of the watchers key with the following code:

    watchers: [node: ["node_modules/webpack/bin/webpack.js", "--mode", "development", "--watch-stdin", "--color", cd: Path.expand("../assets", __DIR__)]]
  18. Configure in the dev.exs and test.exs files the credentials for the databases to be created.

    config :project_name, ProjectName.Repo,
      adapter: Ecto.Adapters.Postgres,
      username: "postgres",
      password: "pass",
      database: "project_name_dev",
      hostname: "localhost",
      pool_size: 10
  19. Access to the project_name\lib\project_name_web\templates\layout directory of the project.

    cd ..\lib\project_name_web\templates\layout
  20. Edit the app.html.eex file and replace the tag <body> and its content with the following code:

    <body>
      <main role="main">
        <%= render @view_module, @view_template, assigns %>
      </main>
      <script src="<%= static_path(@conn, "/js/app.js") %>"></script>
    </body>
  21. Access to the project_name\lib\project_name_web\templates\page directory of the project.

    cd ..\page
  22. Edit the index.html.eex file and replace all the content with the following code:

    <div id="root"></div>
  23. Access to the root directory of the project: project_name.

    cd ..\..\..\..
  24. Edit the mix.exs and add the following dependencies:

    {:plug_cowboy, "~> 1.0"},
    {:absinthe, "~> 1.4.13"},
    {:absinthe_ecto, "~> 0.1.3"},
    {:absinthe_plug, "~> 1.4.6"},
    {:absinthe_phoenix, "~> 1.4.3"}

    Delete the following dependency in the same file:

    {:cowboy, "~> 1.0"}
  25. Access to the project_name\lib\project_name_web directory of the project.

    cd lib\project_name_web
  26. Edit the router.ex file and add the following code after de last scope:

    if Mix.env == :dev do
      forward "/graphiql", Absinthe.Plug.GraphiQL,
        schema: ProjectName.Graphql.Schema,
        interface: :advanced,
        context: %{pubsub: ProjectName.Endpoint}
    end

    Do not forget to replace the module name ProjectName in this code with the actual project name.

  27. Access to the project_name\lib\project_name directory of the project.

    cd ..\project_name
  28. Create the graphql directory and access it.

    mkdir graphql && cd graphql
  29. Create a new file with queries.ex as file name.

    touch queries.ex
  30. Edit the queries.ex file and place the following code:

    defmodule ProjectName.Graphql.Queries do
      @moduledoc false
    
      use Absinthe.Schema.Notation
    
      object :queries do
      end
    end

    Do not forget to replace the module name ProjectName in this code with the actual project name.

  31. Create a new file with mutations.ex as file name.

    touch mutations.ex
  32. Edit the mutations.ex file and place the following code:

    defmodule ProjectName.Graphql.Mutations do
      @moduledoc false
    
      use Absinthe.Schema.Notation
    
      object :mutations do
      end
    end

    Do not forget to replace the module name ProjectName in this code with the actual project name.

  33. Create a new file with subscriptions.ex as file name.

    touch subscriptions.ex
  34. Edit the subscriptions.ex file and place the following code:

    defmodule ProjectName.Graphql.Subscriptions do
      @moduledoc false
    
      use Absinthe.Schema.Notation
    
      object :subscriptions do
      end
    end

    Do not forget to replace the module name ProjectName in this code with the actual project name.

  35. Create a new file with schema.ex as file name.

    touch schema.ex
  36. Edit the schema.ex file and place the following code:

    defmodule ProjectName.Graphql.Schema do
      @moduledoc false
    
      use Absinthe.Schema
    
      import_types ProjectName.Graphql.Queries
      import_types ProjectName.Graphql.Mutations
      import_types ProjectName.Graphql.Subscriptions
      import_types Absinthe.Plug.Types
      import_types Absinthe.Type.Custom
    
      query [], do: import_fields :queries
      mutation [], do: import_fields :mutations
      subscription [], do: import_fields :subscriptions
    end

    Do not forget to replace the module name ProjectName in this code with the actual project name.

  37. Access to the root directory of the project: project_name.

    cd ..\..\..
  38. Update and compile the new dependencies of the Phoenix project.

    mix deps.get && mix deps.compile
  39. Create the project database.

    mix ecto.create

To verify that the project has been correctly configured, the server must be initialized with the command:

mix phx.server

In the browser enter the URL localhost:4000. If it displays a blank page with a single text "Ok" and shows no errors or warnings in both the server and the browser console, the configuration has been successful.

Script

This is a tool that allows you to automatically create and configure a new project. This is a Bash script, to use it it is necessary to execute it in a terminal that can execute this interface.

Download link: S1.project.sh

To be able to run it on Unix-based systems it will be necessary to give it execution permissions:

chmod +x s1.project.sh

Project Structure

Backend

Under redaction.

Frontend

Under redaction.

Languages

Copying

License

Creative Commons License This work is licensed under a Creative Commons Attribution 3.0 Unported License.

About

Guide for the initial configuration for projects that are built with the following technologies stack: Phoenix Framework, Webpack Module Bundler, React Library and GraphQL Query Language and how each element should be organized in the internal structure of the project.

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages