Migrate from webpack to esbuild
@@ -6,7 +6,7 @@ Dockerfile
|
||||
Makefile
|
||||
README*
|
||||
test/
|
||||
priv/static/
|
||||
priv/static/assets
|
||||
**/node_modules
|
||||
import/
|
||||
teslamate.bck
|
||||
|
||||
@@ -31,7 +31,7 @@ npm-debug.log
|
||||
# Since we are building assets from assets/,
|
||||
# we ignore priv/static. You may want to comment
|
||||
# this depending on your deployment strategy.
|
||||
/priv/static/
|
||||
/priv/static/assets
|
||||
|
||||
# CDLR data repository
|
||||
/priv/cldr/
|
||||
|
||||
@@ -22,8 +22,8 @@ COPY assets/package.json assets/package-lock.json ./assets/
|
||||
RUN npm ci --prefix ./assets --progress=false --no-audit --loglevel=error
|
||||
|
||||
COPY assets assets
|
||||
RUN npm run deploy --prefix ./assets && \
|
||||
mix phx.digest
|
||||
COPY priv/static priv/static
|
||||
RUN mix assets.deploy
|
||||
|
||||
COPY lib lib
|
||||
COPY priv/repo/migrations priv/repo/migrations
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
"@babel/preset-env"
|
||||
]
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
@charset "utf-8";
|
||||
|
||||
@import "~leaflet/dist/leaflet.css";
|
||||
@import "~leaflet-control-geocoder/dist/Control.Geocoder.css";
|
||||
@import "~@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css";
|
||||
@import "leaflet/dist/leaflet.css";
|
||||
@import "leaflet-control-geocoder/dist/Control.Geocoder.css";
|
||||
@import "@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css";
|
||||
|
||||
$mdi-font-path: "~@mdi/font/fonts";
|
||||
@import "~@mdi/font/scss/materialdesignicons.scss";
|
||||
$mdi-font-path: "@mdi/font/fonts";
|
||||
@import "@mdi/font/scss/materialdesignicons.scss";
|
||||
|
||||
$notification-padding: 0.75rem 1.25rem 0.75rem 0.75rem;
|
||||
$widescreen-enabled: false;
|
||||
$fullhd-enabled: false;
|
||||
|
||||
@import "~bulma/sass/utilities/_all";
|
||||
@import "~bulma/sass/base/_all";
|
||||
@import "~bulma/sass/helpers/_all.sass";
|
||||
@import "bulma/sass/utilities/_all";
|
||||
@import "bulma/sass/base/_all";
|
||||
@import "bulma/sass/helpers/_all.sass";
|
||||
|
||||
// Modal customization
|
||||
$modal-z: 1010;
|
||||
@@ -24,28 +24,28 @@ $modal-card-head-background-color: $white;
|
||||
$modal-card-head-border-bottom: none;
|
||||
$modal-card-foot-border-top: none;
|
||||
|
||||
@import "~bulma/sass/components/breadcrumb";
|
||||
@import "~bulma/sass/components/card";
|
||||
@import "~bulma/sass/components/dropdown";
|
||||
@import "~bulma/sass/components/message";
|
||||
@import "~bulma/sass/components/modal";
|
||||
@import "~bulma/sass/components/navbar";
|
||||
@import "~bulma/sass/components/tabs";
|
||||
@import "~bulma/sass/elements/box";
|
||||
@import "~bulma/sass/elements/button";
|
||||
@import "~bulma/sass/elements/container";
|
||||
@import "~bulma/sass/elements/icon";
|
||||
@import "~bulma/sass/elements/notification";
|
||||
@import "~bulma/sass/elements/table";
|
||||
@import "~bulma/sass/elements/tag";
|
||||
@import "~bulma/sass/elements/title";
|
||||
@import "~bulma/sass/form/_all";
|
||||
@import "~bulma/sass/layout/section";
|
||||
@import "~bulma/sass/grid/_all";
|
||||
@import "bulma/sass/components/breadcrumb";
|
||||
@import "bulma/sass/components/card";
|
||||
@import "bulma/sass/components/dropdown";
|
||||
@import "bulma/sass/components/message";
|
||||
@import "bulma/sass/components/modal";
|
||||
@import "bulma/sass/components/navbar";
|
||||
@import "bulma/sass/components/tabs";
|
||||
@import "bulma/sass/elements/box";
|
||||
@import "bulma/sass/elements/button";
|
||||
@import "bulma/sass/elements/container";
|
||||
@import "bulma/sass/elements/icon";
|
||||
@import "bulma/sass/elements/notification";
|
||||
@import "bulma/sass/elements/table";
|
||||
@import "bulma/sass/elements/tag";
|
||||
@import "bulma/sass/elements/title";
|
||||
@import "bulma/sass/form/_all";
|
||||
@import "bulma/sass/layout/section";
|
||||
@import "bulma/sass/grid/_all";
|
||||
|
||||
@import "~@creativebulma/bulma-tooltip";
|
||||
@import "~@creativebulma/bulma-divider";
|
||||
@import "~bulma-switch";
|
||||
@import "@creativebulma/bulma-tooltip";
|
||||
@import "@creativebulma/bulma-divider";
|
||||
@import "bulma-switch";
|
||||
|
||||
@import "./vendor/modal-fx";
|
||||
|
||||
|
||||
@@ -163,7 +163,6 @@ export const SimpleMap = {
|
||||
const map = createMap({
|
||||
elId: this.el.dataset.id,
|
||||
zoomControl: !!this.el.dataset.zoom,
|
||||
dragging: false,
|
||||
boxZoom: false,
|
||||
doubleClickZoom: false,
|
||||
keyboard: false,
|
||||
@@ -202,92 +201,86 @@ export const TriggerChange = {
|
||||
},
|
||||
};
|
||||
|
||||
import("leaflet-control-geocoder");
|
||||
import("@geoman-io/leaflet-geoman-free");
|
||||
|
||||
export const Map = {
|
||||
mounted() {
|
||||
Promise.all([
|
||||
import(
|
||||
/* webpackPreload: true, webpackChunkName: "geo" */ "leaflet-control-geocoder"
|
||||
),
|
||||
import(
|
||||
/* webpackPreload: true, webpackChunkName: "geo" */ "@geoman-io/leaflet-geoman-free"
|
||||
),
|
||||
]).then(() => {
|
||||
const geoFence = (name) =>
|
||||
document.querySelector(`input[name='geo_fence[${name}]']`);
|
||||
const geoFence = (name) =>
|
||||
document.querySelector(`input[name='geo_fence[${name}]']`);
|
||||
|
||||
const $radius = geoFence("radius");
|
||||
const $latitude = geoFence("latitude");
|
||||
const $longitude = geoFence("longitude");
|
||||
const $radius = geoFence("radius");
|
||||
const $latitude = geoFence("latitude");
|
||||
const $longitude = geoFence("longitude");
|
||||
|
||||
const location = new LatLng($latitude.value, $longitude.value);
|
||||
const location = new LatLng($latitude.value, $longitude.value);
|
||||
|
||||
const controlOpts = {
|
||||
position: "topleft",
|
||||
cutPolygon: false,
|
||||
drawCircle: false,
|
||||
drawCircleMarker: false,
|
||||
drawMarker: false,
|
||||
drawPolygon: false,
|
||||
drawPolyline: false,
|
||||
drawRectangle: false,
|
||||
removalMode: false,
|
||||
};
|
||||
const controlOpts = {
|
||||
position: "topleft",
|
||||
cutPolygon: false,
|
||||
drawCircle: false,
|
||||
drawCircleMarker: false,
|
||||
drawMarker: false,
|
||||
drawPolygon: false,
|
||||
drawPolyline: false,
|
||||
drawRectangle: false,
|
||||
removalMode: false,
|
||||
};
|
||||
|
||||
const editOpts = {
|
||||
allowSelfIntersection: false,
|
||||
preventMarkerRemoval: true,
|
||||
};
|
||||
const editOpts = {
|
||||
allowSelfIntersection: false,
|
||||
preventMarkerRemoval: true,
|
||||
};
|
||||
|
||||
const map = createMap({ enableHybridLayer: true });
|
||||
map.setView(location, 17, { animate: false });
|
||||
map.pm.setLang(LANG);
|
||||
map.pm.addControls(controlOpts);
|
||||
map.pm.enableGlobalEditMode(editOpts);
|
||||
const map = createMap({ enableHybridLayer: true });
|
||||
map.setView(location, 17, { animate: false });
|
||||
map.pm.setLang(LANG);
|
||||
map.pm.addControls(controlOpts);
|
||||
map.pm.enableGlobalEditMode(editOpts);
|
||||
|
||||
const circle = new Circle(location, { radius: $radius.value })
|
||||
.addTo(map)
|
||||
.on("pm:edit", (e) => {
|
||||
const { lat, lng } = e.target.getLatLng();
|
||||
const radius = Math.round(e.target.getRadius());
|
||||
const circle = new Circle(location, { radius: $radius.value })
|
||||
.addTo(map)
|
||||
.on("pm:edit", (e) => {
|
||||
const { lat, lng } = e.target.getLatLng();
|
||||
const radius = Math.round(e.target.getRadius());
|
||||
|
||||
$radius.value = radius;
|
||||
$latitude.value = lat;
|
||||
$longitude.value = lng;
|
||||
$radius.value = radius;
|
||||
$latitude.value = lat;
|
||||
$longitude.value = lng;
|
||||
|
||||
const mBox = map.getBounds();
|
||||
const cBox = circle.getBounds();
|
||||
const bounds = mBox.contains(cBox) ? mBox : cBox;
|
||||
map.fitBounds(bounds);
|
||||
});
|
||||
const mBox = map.getBounds();
|
||||
const cBox = circle.getBounds();
|
||||
const bounds = mBox.contains(cBox) ? mBox : cBox;
|
||||
map.fitBounds(bounds);
|
||||
});
|
||||
|
||||
new Control.geocoder({ defaultMarkGeocode: false })
|
||||
.on("markgeocode", (e) => {
|
||||
const { bbox, center } = e.geocode;
|
||||
new Control.geocoder({ defaultMarkGeocode: false })
|
||||
.on("markgeocode", (e) => {
|
||||
const { bbox, center } = e.geocode;
|
||||
|
||||
const poly = L.polygon([
|
||||
bbox.getSouthEast(),
|
||||
bbox.getNorthEast(),
|
||||
bbox.getNorthWest(),
|
||||
bbox.getSouthWest(),
|
||||
]);
|
||||
const poly = L.polygon([
|
||||
bbox.getSouthEast(),
|
||||
bbox.getNorthEast(),
|
||||
bbox.getNorthWest(),
|
||||
bbox.getSouthWest(),
|
||||
]);
|
||||
|
||||
circle.setLatLng(center);
|
||||
circle.setLatLng(center);
|
||||
|
||||
const lBox = poly.getBounds();
|
||||
const cBox = circle.getBounds();
|
||||
const bounds = cBox.contains(lBox) ? cBox : lBox;
|
||||
const lBox = poly.getBounds();
|
||||
const cBox = circle.getBounds();
|
||||
const bounds = cBox.contains(lBox) ? cBox : lBox;
|
||||
|
||||
map.fitBounds(bounds);
|
||||
map.pm.enableGlobalEditMode();
|
||||
map.fitBounds(bounds);
|
||||
map.pm.enableGlobalEditMode();
|
||||
|
||||
const { lat, lng } = center;
|
||||
$latitude.value = lat;
|
||||
$longitude.value = lng;
|
||||
})
|
||||
.addTo(map);
|
||||
const { lat, lng } = center;
|
||||
$latitude.value = lat;
|
||||
$longitude.value = lng;
|
||||
})
|
||||
.addTo(map);
|
||||
|
||||
map.fitBounds(circle.getBounds(), { animate: false });
|
||||
});
|
||||
map.fitBounds(circle.getBounds(), { animate: false });
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
{
|
||||
"repository": {},
|
||||
"description": "...",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"deploy": "webpack --mode production --stats-colors",
|
||||
"watch": " webpack --mode development --watch --watch-options-stdin --stats-colors"
|
||||
"deploy": "node scripts/build.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@creativebulma/bulma-divider": "^1.1.0",
|
||||
"@creativebulma/bulma-tooltip": "^1.2.0",
|
||||
"@geoman-io/leaflet-geoman-free": "^2.11.2",
|
||||
"@mdi/font": "^5.9.55",
|
||||
"@mdi/font": "^6.1.95",
|
||||
"bulma-switch": "^2.0.0",
|
||||
"glob": "^7.1.7",
|
||||
"leaflet": "^1.7.1",
|
||||
"leaflet-control-geocoder": "^2.3.0",
|
||||
"phoenix": "file:../deps/phoenix",
|
||||
@@ -19,21 +18,10 @@
|
||||
"phoenix_live_view": "file:../deps/phoenix_live_view"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.6",
|
||||
"@babel/preset-env": "^7.14.7",
|
||||
"babel-loader": "^8.2.2",
|
||||
"bulma": "^0.9.3",
|
||||
"copy-webpack-plugin": "^9.0.1",
|
||||
"css-loader": "^5.2.6",
|
||||
"css-minimizer-webpack-plugin": "^3.0.2",
|
||||
"file-loader": "^6.2.0",
|
||||
"mini-css-extract-plugin": "^1.6.2",
|
||||
"sass": "^1.35.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"terser-webpack-plugin": "^5.1.4",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack": "^5.41.1",
|
||||
"webpack-cli": "^4.7.2"
|
||||
"esbuild": "^0.13.0",
|
||||
"esbuild-sass-plugin": "^1.5.5",
|
||||
"sass": "^1.42.1"
|
||||
},
|
||||
"name": "assets"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { sassPlugin } = require("esbuild-sass-plugin");
|
||||
const esbuild = require("esbuild");
|
||||
|
||||
const ENTRY_FILE = "app.js";
|
||||
const OUTPUT_DIR = path.resolve(__dirname, "../../priv/static/assets");
|
||||
const OUTPUT_FILE = "app.js";
|
||||
const MODE = process.env["NODE_ENV"] || "production";
|
||||
const TARGET = "es2016";
|
||||
|
||||
const isDevMode = MODE === "development";
|
||||
|
||||
const build_opts = {
|
||||
entryPoints: [path.join(__dirname, "..", "js", ENTRY_FILE)],
|
||||
outfile: `${OUTPUT_DIR}/${OUTPUT_FILE}`,
|
||||
minify: !isDevMode,
|
||||
watch: isDevMode,
|
||||
bundle: true,
|
||||
target: TARGET,
|
||||
logLevel: "silent",
|
||||
loader: {
|
||||
".png": "dataurl",
|
||||
".ttf": "file",
|
||||
".otf": "file",
|
||||
".svg": "file",
|
||||
".eot": "file",
|
||||
".woff": "file",
|
||||
".woff2": "file",
|
||||
},
|
||||
plugins: [sassPlugin()],
|
||||
define: {
|
||||
"process.env.NODE_ENV": isDevMode ? '"development"' : '"production"',
|
||||
global: "window",
|
||||
},
|
||||
sourcemap: isDevMode,
|
||||
};
|
||||
|
||||
async function build() {
|
||||
try {
|
||||
console.log(`[+] Starting static assets build with esbuild (${MODE})...`);
|
||||
await esbuild.build(build_opts);
|
||||
console.log(`[+] Esbuild ${ENTRY_FILE} to ${OUTPUT_DIR} succeeded.`);
|
||||
} catch (e) {
|
||||
console.error("[-] Error building:", e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs.existsSync(OUTPUT_DIR)) fs.mkdirSync(OUTPUT_DIR);
|
||||
|
||||
build();
|
||||
@@ -1,65 +0,0 @@
|
||||
const path = require("path");
|
||||
const glob = require("glob");
|
||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
|
||||
module.exports = (env, options) => ({
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [`...`, new TerserPlugin(), new CssMinimizerPlugin()],
|
||||
},
|
||||
entry: {
|
||||
app: glob.sync("./vendor/**/*.js").concat(["./js/app.js"]),
|
||||
},
|
||||
output: {
|
||||
publicPath: "/js/",
|
||||
path: path.resolve(__dirname, "../priv/static/js"),
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: "babel-loader",
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.s(c|a)ss$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
"css-loader",
|
||||
{
|
||||
loader: "sass-loader",
|
||||
options: {
|
||||
implementation: require("sass"),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
loader: "url-loader",
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: "../images/[name].[contenthash:7].[ext]",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
loader: "url-loader",
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: "../fonts/[name].[contenthash:7].[ext]",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({ filename: "../css/app.css" }),
|
||||
new CopyWebpackPlugin({ patterns: [{ from: "static/", to: "../" }] }),
|
||||
],
|
||||
});
|
||||
@@ -5,14 +5,11 @@ config :teslamate, TeslaMateWeb.Endpoint,
|
||||
code_reloader: true,
|
||||
check_origin: false,
|
||||
watchers: [
|
||||
node: [
|
||||
"node_modules/webpack/bin/webpack.js",
|
||||
"--mode",
|
||||
"development",
|
||||
"--stats-colors",
|
||||
"--watch",
|
||||
"--watch-options-stdin",
|
||||
cd: Path.expand("../assets", __DIR__)
|
||||
npm: [
|
||||
"run",
|
||||
"deploy",
|
||||
cd: Path.expand("../assets", __DIR__),
|
||||
env: %{"NODE_ENV" => "development"}
|
||||
]
|
||||
],
|
||||
live_reload: [
|
||||
|
||||
@@ -13,7 +13,7 @@ defmodule TeslaMateWeb.Endpoint do
|
||||
socket "/live", Phoenix.LiveView.Socket,
|
||||
websocket: [connect_info: [session: @session_options], transport_log: :debug]
|
||||
|
||||
@only ~w(css fonts images js favicon.ico robots.txt android-chrome-192x192.png
|
||||
@only ~w(assets fonts images favicon.ico robots.txt android-chrome-192x192.png
|
||||
android-chrome-512x512.png apple-touch-icon.png browserconfig.xml
|
||||
favicon-16x16.png favicon-32x32.png mstile-150x150.png
|
||||
safari-pinned-tab.svg site.webmanifest)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<%= live_title_tag assigns[:page_title] || "Home", suffix: " · TeslaMate" %>
|
||||
<link rel="stylesheet" href={Routes.static_path(@conn, "/css/app.css")}/>
|
||||
<link phx-track-static rel="stylesheet" href={Routes.static_path(@conn, "/assets/app.css")}/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=5AB53N3ALo">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png?v=5AB53N3ALo">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png?v=5AB53N3ALo">
|
||||
@@ -15,7 +15,7 @@
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<%= csrf_meta_tag() %>
|
||||
<script defer src={Routes.static_path(@conn, "/js/app.js")}></script>
|
||||
<script defer phx-track-static type="text/javascript" src={Routes.static_path(@conn, "/assets/app.js")}></script>
|
||||
</head>
|
||||
<body tabIndex="0">
|
||||
<nav class="navbar is-dark" role="navigation" aria-label="main navigation">
|
||||
|
||||
@@ -66,9 +66,11 @@ defmodule TeslaMate.MixProject do
|
||||
|
||||
defp aliases do
|
||||
[
|
||||
setup: ["deps.get", "ecto.setup", "cmd --cd assets npm ci --no-audit --loglevel=error"],
|
||||
"ecto.setup": ["ecto.create", "ecto.migrate"],
|
||||
"ecto.reset": ["ecto.drop", "ecto.setup"],
|
||||
test: ["ecto.create --quiet", "ecto.migrate", "test --no-start"],
|
||||
"assets.deploy": ["cmd --cd assets npm run deploy", "phx.digest"],
|
||||
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test --no-start"],
|
||||
ci: ["format --check-formatted", "test --raise"]
|
||||
]
|
||||
end
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 679 B After Width: | Height: | Size: 679 B |
|
Before Width: | Height: | Size: 297 B After Width: | Height: | Size: 297 B |
|
Before Width: | Height: | Size: 473 B After Width: | Height: | Size: 473 B |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 524 B After Width: | Height: | Size: 524 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 851 B After Width: | Height: | Size: 851 B |
@@ -6,26 +6,21 @@ sidebar_label: Development and Contributing
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Elixir** >= 1.11
|
||||
- **Elixir** >= 1.12
|
||||
- **Postgres** >= 10
|
||||
- An **MQTT broker** e.g. mosquitto (_optional_)
|
||||
- **NodeJS** >= 14
|
||||
|
||||
## Initial Setup
|
||||
|
||||
To run the TeslaMate test suite you need a database named `teslamate_test`:
|
||||
|
||||
```bash
|
||||
# download dependencies
|
||||
mix deps.get
|
||||
|
||||
# create the dev database and run migrations
|
||||
mix ecto.setup
|
||||
# download dependencies, create the dev database and run migrations
|
||||
mix setup
|
||||
|
||||
# create the test database
|
||||
MIX_ENV=test mix ecto.setup
|
||||
|
||||
# download JavaScript dependencies
|
||||
npm install --prefix ./assets
|
||||
```
|
||||
|
||||
## Running locally
|
||||
|
||||
@@ -77,10 +77,10 @@ Source: [mosquitto.org/download](https://mosquitto.org/download/)
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Node.js (v12+)</summary>
|
||||
<summary>Node.js (v14+)</summary>
|
||||
|
||||
```bash
|
||||
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
|
||||
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
```
|
||||
|
||||
|
||||
@@ -17,8 +17,9 @@ Click on the following items to view detailed installation steps.
|
||||
pkg install bash
|
||||
bash
|
||||
```
|
||||
|
||||
For simplicity reasons, follow the rest of the tutorial in bash rather the csh.
|
||||
|
||||
For simplicity reasons, follow the rest of the tutorial in bash rather the csh.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@@ -27,6 +28,7 @@ bash
|
||||
```bash
|
||||
pkg install git
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@@ -35,6 +37,7 @@ pkg install git
|
||||
```bash
|
||||
pkg install erlang
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@@ -43,12 +46,12 @@ pkg install erlang
|
||||
Unfortunately the Elixir part is not well updated in FreeBSD ports.
|
||||
Hence the latest supported version for Erlang 21 (latest in FreeBSD ports)
|
||||
is Elixir 1.11.
|
||||
|
||||
|
||||
We will need to compile it from source, which is pretty easy though.
|
||||
|
||||
```bash
|
||||
pkg install gmake
|
||||
|
||||
|
||||
cd /usr/local/src
|
||||
git clone https://github.com/elixir-lang/elixir.git
|
||||
cd elixir
|
||||
@@ -57,6 +60,7 @@ gmake clean test
|
||||
gmake install
|
||||
elixir --version
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@@ -66,7 +70,7 @@ elixir --version
|
||||
pkg install postgressql(12|13)-server
|
||||
echo postgres_enable="yes" >> /etc/rc.conf
|
||||
```
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@@ -76,6 +80,7 @@ echo postgres_enable="yes" >> /etc/rc.conf
|
||||
pkg install grafana7
|
||||
echo grafana_enable="yes" >> /etc/rc.conf
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@@ -89,11 +94,12 @@ echo mosquitto_enable="yes" >> /etc/rc.conf
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Node.js (v12+)</summary>
|
||||
<summary>Node.js (v14+)</summary>
|
||||
|
||||
```bash
|
||||
pkg install node(12|14|)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Clone TeslaMate git repository
|
||||
@@ -139,6 +145,7 @@ mix do phx.digest, release --overwrite
|
||||
## Starting TeslaMate at boot time
|
||||
|
||||
### Create FreeBSD service definition _/usr/local/etc/rc.d/teslamate_
|
||||
|
||||
```console
|
||||
# PROVIDE: teslamate
|
||||
# REQUIRE: DAEMON
|
||||
@@ -183,7 +190,7 @@ COMMAND=${teslamate_command-"${HOME}/_build/prod/rel/teslamate/bin/teslamate"}
|
||||
teslamate_start()
|
||||
{
|
||||
${COMMAND} eval "TeslaMate.Release.migrate"
|
||||
${COMMAND} daemon
|
||||
${COMMAND} daemon
|
||||
}
|
||||
|
||||
start_cmd="${name}_start"
|
||||
@@ -196,6 +203,7 @@ run_rc_command "$1"
|
||||
```
|
||||
|
||||
### Update _/etc/rc.conf_
|
||||
|
||||
```bash
|
||||
echo teslamate_enable="YES" >> /etc/rc.conf
|
||||
echo teslamate_db_host="localhost" >> /etc/rc.conf
|
||||
@@ -205,6 +213,7 @@ echo teslamate_disable_mqtt="true" >> /etc/rc.conf
|
||||
```
|
||||
|
||||
### Start service
|
||||
|
||||
```bash
|
||||
service teslamate start
|
||||
```
|
||||
@@ -261,4 +270,3 @@ service teslamate start
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
|
||||