Giter Club home page Giter Club logo

portfolio's Introduction

Vue + tailwind + webpack boilerplate

This boilerplate provides the a simple setup needed to create development and production environments for Vue 3 apps using Tailwind and FontAwesome, building them afterwards into production with Webpack. Everything is explained step by step, to better understand what is going on, so it is easy to use this as the base to start building your own apps. Every step of the setup is fully explained and documented.

Quickstart

To get started simply install the project using npm install and use the following commands:

  • npm run serve:dev to serve the project locally using the development build
  • npm run serve:prod to serve the project locally using the production build
  • npm run build:dev to build the project in development mode, the output will be saved in ๐Ÿ“‚dist. Good to test the development build files generated or to work using an extension like live server
  • npm run build:prod to build the project in production mode, the output will be saved in ๐Ÿ“‚dist. Run this command before putting the application live.

Folder structure

.
โ”œโ”€โ”€ ๐Ÿ“‚dist                    # Distribution folder, contains your latest build
โ”œโ”€โ”€ ๐Ÿ“‚node_modules            # Node dependencies
โ”œโ”€โ”€ ๐Ÿ“‚public                  # Contains the index.html template
โ”œโ”€โ”€ ๐Ÿ“‚src                     # Source code of the application
โ”‚   โ”œโ”€โ”€ ๐Ÿ“‚assets              # Any assets used by the application (images, fonts...)
โ”‚   โ”œโ”€โ”€ ๐Ÿ“‚components          # Folder with all the Vue components used by the application
โ”‚   โ”œโ”€โ”€ ๐Ÿ“‚css                 # All stylesheets used by the Vue components
โ”‚   โ”œโ”€โ”€ ๐Ÿ“œApp.vue             # Top level vue component
โ”‚   โ””โ”€โ”€ ๐Ÿ“œmain.js             # Our application entry point
โ”œโ”€โ”€ โš™๏ธpackage.json            # Configuration file to manage the project dependencies, scripts, version...
โ”œโ”€โ”€ โš™๏ธpostcss.config.js       # Configuration file to manage the postCSS configuration and plugins
โ”œโ”€โ”€ ๐Ÿ“œREADME.md               # This :)
โ”œโ”€โ”€ โš™๏ธtailwind.congif.js      # Configuration file to manage tailwind-specific options
โ””โ”€โ”€ โš™๏ธwebpack.config.js       # Main webpack's configuration file

Installing vue

The first thing is to install Vue 3 running the following command:

npm install vue

๐Ÿ“ NOTE: If Vue 3 is not yet the main release use the command npm install vue@latest

Installing webpack

Next thing is to install webpack. From now on all dependencies are used only during development so they will all include the -D flag.

npm install -D webpack webpack-cli
  • webpack: This installs the webpack main functionalities
  • webpack-cli: Since webpack version 4, the command line interface (CLI) got removed from the main package and added to its own repo and package. If you want to access the webpack command install this too. These two first dependencies make up for the most basic local webpack installation (docs)

๐Ÿ“ NOTE: The CLI is linked inside the node_modules/.bin folder. This means that you won't be able to use webpack normally through the console but your scripts inside package.json will access it without issue.

๐Ÿ“ NOTE: You can still access the webpack commands using the npx command shipped with Node 8.2/npm 5.2.0. You can try to run npx webpack --version to check if the command works and see the installed dependencies versions.

Installing Vue-loader

Vue loader is a webpack loader that allows us to process Single-File Components (SFC). (docs)

npm install -D vue-loader vue-template-compiler style-loader css-loader 
  • vue-loader: This installs the main vue-loader functionalities
  • vue-template-compiler: The vue-template-compiler has two primary functions: converting templates to render() functions and parsing single file componens.
  • style-loader: Adds CSS to the DOM by injecting a <style> tag (docs)
  • css-loader: Gives you more control over importing .css files. (docs)

๐Ÿ“ NOTE: On the docs it is mentioned to use the vue-style-loader but this loader is not well maintained. Instead we will use the style-loader provided by webpack.

๐Ÿ“ NOTE: We need to import css-loader since it is not a dependency of vue-loader anymore.

Related webpack configuration

const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {

    module: {
        rules: [{
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    //other css loaders
                ]
            },
            //other rules
        ]
    },
    plugins: [
        new VueLoaderPlugin(),
        //other plugins
    ]
    ...
}

Installing html-webpack-plugin

This plugin will create and dynamically inject the dependencies of our application into the main HTML file. (docs)

npm install --save-dev html-webpack-plugin

Since the HTML file created needs to have a \<div id="app"\> tag to load our Vue components in, we will be using a template located in public/index.html.

Related webpack configuration

const path = require('path')

module.exports = {
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'public/index.html')
        }),
        //other plugins
    ],
}

Installing tailwind

Now we will install the tailwindCSS library for our CSS styling on the page (docs)

npm install -D tailwindcss postcss autoprefixer postcss-import postcss-loader
  • tailwindcss: Installs the main tailwind functionalities
  • postcss: A tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more (docs)
  • postcss-loader: A webpack loader to process CSS with PostCSS (docs)
  • autoprefixer: Parses CSS files adding vendor prefixes to CSS rules so you can forget and write normal CSS (docs)
  • postcss-import: Offers the ability to organize your CSS into multiple files and combine them at build time by processing @import statements in advance (docs)

Related webpack configuration

Aside from the webpack.config.js file, we will create the postcss configuration inside the postcss.config.js file. The first thing is to call this loader from our webpack file:

webpack.config.js

const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [{
                        loader: 'css-loader',
                        options: {
                            // 0 => no loaders (default);
                            // 1 => postcss-loader;
                            // 2 => postcss-loader, sass-loader
                            importLoaders: 1
                        }
                    },
                    //other loaders
                    'postcss-loader'
                ]
            },
            //other rules
        ]
    },

}

postcss.config.js calling the needed plugins to process the tailwindCSS files and loading the tailwind configuration.

module.exports = {
  plugins: [
    require("postcss-import"),
    require("tailwindcss"),
    require("autoprefixer"),
  ],
};

Configuring tailwind

In order to integrate tailwind there are additional steps to take, first of all we will initialize its configuration file:

npx tailwind init

This will create the tailwind.config.js file. Next we need to create a css file that includes all of the tailwind functionalities. This file is located under src/css/tailwind.css and simply contains the following imports:

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

Finally this needs to be imported from our main.js file, in this case using the line import './css/tailwind.css';

๐Ÿ“ NOTE: PurgeCSS is not needed with Tailwind 3 since it uses a new engine that generates only the styles you need. (docs)

Setting up a webpack dev server

To test our builds we will set up a simple server used to test our project locally (docs)

npm install -D webpack-dev-server

Related webpack configuration

In order to use the development server, we first need to configure a few fields:

  • entry: This defines the entry point for our webpack process (docs)
  • devtool: This option if and how source maps are generated (docs). They are useful for debugging once a bug is reproduced in a production environment, but will slow down build times.
  • devServer: The devServer configuration
    • open: Tells dev-server to open the browser after server had been started.
    • devMiddleware: Provide options to webpack-dev-middleware which handles webpack assets.
      • writeToDisk: Tells devServer to write generated assets to the disk.
    • static: This option allows configuring options for serving static files from the directory
      • watch: When enabled, it will look for changes on the entry file and its dependencies and will trigger a full page reload if it finds any
const path = require('path')

module.exports = {
    entry: path.join(__dirname, 'src/main.js'),
    devServer: {
        open: true,
        devMiddleware: {
            writeToDisk: true,
        },
        static: {
            watch: true,
        },
    },
}

Setting up MiniCssExtractPlugin

This plugin extracts all our styles into separate .css files, one for each .js file in our application. In our case this will only generate a sinlge .css file from our main.js file (docs). To install we run:

npm install -D mini-css-extract-plugin

Related webpack configuration

Once installed, we only need to configure it on our webpack.config.js file:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    module: {
        rules: [
            //other rules
            {
                test: /\.css$/,
                use: [
                    // other loaders
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            esModule: false,
                        },
                    },

                ]
            },
        ]
    },
    plugins: [
        // other plugins
        new MiniCssExtractPlugin(),
    ],
  // other config
}

Setting up CssMinimizerPlugin

Even though or styles files are not huge, we can cut them in half of what's left by just minifying their contents. To start first we need to install the dependency (docs):

npm install -D mini-css-extract-plugin

Related webpack configuration

Following the docs above we only need to configure the CssMinimizerPlugin as an additional optimization step:

const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
    // other config
    optimization: {
        minimizer: [
          // For webpack@5 you can use the `...` syntax to extend existing minimizers
          '...',
          new CssMinimizerPlugin(),
        ],
      },
}

Since webpack version >4, the optimizations are set automatically for you, but they can be extended this way. Webpack includes webpack-terser-plugin by default in order to minify the .js files too. For this reason we want to make sure to uncomment the '...' part so the rest of the optimization steps provided by webpack are left as is. The configuration above would be similar to the following (note that webpack takes more optimization steps in addition to minifying the .js files):

// This serves just as an example, webpack provides more optimization steps when using '...'
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");

module.exports = {
    // other config
    optimization: {
        minimizer: [
          // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
          new TerserPlugin(),
          new CssMinimizerPlugin(),
        ],
      },
}

๐Ÿ“ NOTE: In the docs you can see the minimize: true option. This is also set depending on whether you are running in development or productio mode. In this project, the mode is defined through the --mode flag on the package.json commands and there is no need to include the minimize option.

Setting up FontAwesome for our icons

We will add a few icons to our interface too. To do so the choice is fontawesome since it has a nice support for Tree Shaking (docs) as well as a package for vue specifically called vue-fontawesome. To get started:

npm install -D @fortawesome/fontawesome-svg-core @fortawesome/vue-fontawesome@latest @fortawesome/free-solid-svg-icons @fortawesome/free-regular-svg-icons
  • @fortawesome/fontawesome-svg-core: This contains the core javascript api (docs)
  • @fortawesome/vue-fontawesome@latest: Has the component we will use on our Vue application to render the icons (docs)
  • @fortawesome/free-solid-svg-icons: The package of solid icons of fontawesome
  • @fortawesome/free-regular-svg-icons: The package of regular icons of fontawesome

๐Ÿ“ NOTE: In this case we will work with the free icons of font awesome, you can find how to import the solid, regular, brand or pro icons on the "add more styles or pro icons" section in the docs

๐Ÿ“ NOTE: If the default fontawesome import is still for versions 2.x of vue, use npm i -D @fortawesome/vue-fontawesome@prerelease

Configuring font awesome

We want to import the needed icons on each component instead of importing them all globally. To do so we will add the following lines on our main.js file to import the dependency and register the component:

...
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
...

const app = createApp(App)
  .component("font-awesome-icon", FontAwesomeIcon)
  .mount("#app");

Once the library is imported and the component registered, whenever we want to use an icon first we will import the icon, the library and then add the icon to the library and finally use them in our template, for example:

<script>
import { faAddressBook } from "@fortawesome/free-solid-svg-icons";
import { library } from "@fortawesome/fontawesome-svg-core";

export default {
  beforeCreate() {
    library.add(faAddressBook);
  },
};
</script>
<template>
  <font-awesome-icon :icon="['fas', 'address-book']" />
</template>

๐Ÿ“ NOTE: I recommend going through the docs if you've never used font awesome before and you can also search for icons here.

๐Ÿ“ NOTE: There are two things to look our for when using fontAwesome. The first thins is that, while the import name is in camelCase, the element itself will use kebab-case. The second thing is that you need to make sure that you are using the right prefix (fas for solid, far for regular and fab for brands).

Setting up dark mode with Tailwind.css

Dark mode support comes built-in with Tailwind.css making things much easier to set up (docs). This mode is disabled by default in order to keep the size at a minimum and needs to be enabled on the tailwind.config.js file by setting the darkMode option:

tailwind.config.js

module.exports = {
  content: [
    './src/**/*.html',
    './src/**/*.vue',
    './src/*.js',
    './src/*.vue',
  ],
  darkMode: 'class', // or 'media' or false
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

Since we want to toggle the dark mode manually through the use of a class we will set the darkMode option to class. Then on our root element we will set that class dynamically when the user clicks on the moon icon at the bottom-left corner:

src/App.vue

<template>
  <div :class="{ dark: isDarkModeActive }">
    <div class="flex flex-row h-screen antialiased text-gray-800">
      <Sidebar @toggle-dark-mode="isDarkModeActive = !isDarkModeActive" />
      <Chat />
    </div>
  </div>
</template>

Using this approach, we will receive an event from the Sidebar.vue component (where the moon button is) that will toggle the isDarkModeActive variable to activate the dark class conditionally, applying the styles on all the page accordingly.

Troubleshooting

If you are finding any trouble with this project, you can try one of the following methods to try and solve any issues you may be facing:

Upgrade version

Having older versions of NPM and node may throw errors. This project has been tested with the following minimum verions (ref):

  • Node: 15.6.0
  • NPM: 7.4.0

If your project works with previous of Node or NPM open an issue to fix this section.

Other

portfolio's People

Contributors

aridez avatar j3lmer avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.