Skip to content

deprecated Getting started with a bundled project

andy.rothwell edited this page Mar 18, 2019 · 1 revision

Note

There is a big update coming to this section in March, as we are going to encourage people to use Vue Cli 3 to build their bundled projects from now on. This will simplify all of the instructions below, as this system will handle most of the Webpack issues that are discussed below.

See more info in this Bundling Beta section.

Software Installations Needed

Node for using the command line for downloading modules and hosting a development endpoint - https://nodejs.org/en/

Yarn for downloading modules and running webpack - https://yarnpkg.com/en/

Yarn

To get started you'll need to create a folder for an app project, and in a command console, from that folder, run:

yarn init

This will create a package.json file within the project folder.

You will then need to install packages with yarn which are dependencies and development dependencies for the project:

yarn add @philly/mapboard account moment

yarn add @babel/core babel-loader @babel/preset-env cross-env css-loader file-loader style-loader webpack webpack-cli
webpack-dev-server webpack-visualizer-plugin --dev

Add anything else below to make your package.json look like this:

{
  "name": "atlas",
  "version": "0.0.2",
  "description": "A map-based data viewer for the City of Philadelphia",
  "main": "",
  "repository": "https://github.com/cityofphiladelphia/atlas",
  "author": "City of Philadelphia <maps@phila.gov>",
  "license": "MIT",
  "private": false,
  "scripts": {
    "build": "cross-env NODE_ENV=production npx webpack",
    "dev": "cross-env NODE_ENV=development webpack-dev-server"
  },
  "dependencies": {
    "@philly/mapboard": "^3.0.23",
    "accounting": "^0.4.1",
    "axios": "^0.18.0",
    "moment": "^2.21.0",
    "phila-standards": "^1.0.2"
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/preset-env": "^7.2.3",
    "@babel/register": "^7.0.0",
    "babel-loader": "^8.0.5",
    "babel-plugin-component": "^1.1.1",
    "cross-env": "^5.1.4",
    "css-loader": "^0.28.11",
    "file-loader": "^1.1.11",
    "style-loader": "^0.20.3",
    "webpack": "4.2.0",
    "webpack-cli": "^2.0.13",
    "webpack-dev-server": "^3.1.1",
    "webpack-visualizer-plugin": "^0.1.11"
  },
  "babel": {
    "presets": [
      "@babel/preset-env"
    ]
  }
}

Webpack

Create the file webpack.config.js. Paste in this content:

const path = require('path');
const webpack = require('webpack');

const env = process.env.NODE_ENV;
const isDevelopment = env === 'development';

const Visualizer = require('webpack-visualizer-plugin');

module.exports = {
  entry: {
    app: ['./public/index.html', './public/styles.css', './src/main.js'],
  },
  resolve: {
    mainFields: ['module', 'main', 'browser'],
  },
  devtool: isDevelopment ? 'inline-source-map' : 'source-map',
  devServer: {
    contentBase: './dist',
    host: 'localhost',
    port: 8080
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
    publicPath: '/',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      },
      {
        test: /\.html/,
        loader: 'file-loader?name=[name].[ext]',
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: 'images/[name].[ext]?[hash]',
        },
      },
    ],
    },
    plugins: [
      new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),
      new Visualizer({ filename: './statistics.html' })
    ],
    mode: env,
    optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /node_modules/,
          chunks: 'initial',
          name: 'vendor',
          enforce: true,
          priority: 5,
        },
        mapboard: {
          test: /mapboard/,
          chunks: 'initial',
          name: 'mapboard',
          priority: 10,
        },
      },
    },
  },
};

index.html

you'll need to add the following tags to your HTML file.

A full working example can be found in the /example folder in the code base. The following snippets are provided for convenience but may not be as up-to-date as the code.

CSS

<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/ui-lightness/jquery-ui.css">
<link rel="stylesheet" href="//unpkg.com/phila-standards@0.12.0/dist/css/phila-app.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link rel="stylesheet" href="//unpkg.com/Leaflet.vector-markers@0.0.6/dist/leaflet-vector-markers.css">

JavaScript

These are best added to the bottom of the HTML file, just before the closing </body> tag.

<!-- JS: Foundation -->
<script src="//code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

<!-- JS: Cyclomedia (optional) -->
<script src="//cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ol3/4.1.0/ol.js"></script>
<script src="//streetsmart.cyclomedia.com/api/v18.4/StreetSmartApi.js"></script>

<script src="vendor.js"></script>
<script src="mapboard.js"></script>
<script src="app.js"></script>

Mapboard container

Before we start configuring a Mapboard, we'll need an empty DOM element for it to mount to. Add a tag like this wherever you'd like your Mapboard to appear:

<div id="mapboard"></div>

You can use a different id and specify it in the config. See below for details.

Initialization

Now that we've imported the Mapboard JavaScript library into our main.js, we have access to the Mapboard global variable which allows us to create and configure the Mapboard itself. The basic pattern is:

mapboard({
  // config options will go here
});

Note that Mapboard won't initialize without some required options, so if you run that code you might get a few errors at this point.

Clone this wiki locally