To demonstrate - lets say we want to use this code that already works:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8"/>
<title>Just some random JS code with lodash/fp</title>
</head>
<body>
<pre id ="displayArea"></pre>
<script type="text/javascript"
src="https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)"></script>
<script type="text/javascript">
/*
works with Chrome Version 60.0.3112.101 (Official Build) (64-bit)
lodash/fp code re-purposed from:
https://simonsmith.io/dipping-a-toe-into-functional-js-with-lodash-fp/#one-more-example
*/
const displayArea = document.getElementById('displayArea');
const items = [
{name: 'baz'},
{name: 'foo'},
{name: 'bar'},
{name: 'bar'},
{name: 'foo'},
];
const getBars = _.filter(
_.flow(
_.get('name'),
_.isEqual('bar')
)
);
displayArea.textContent = JSON.stringify(
getBars(items)
);
</script>
</body>
</html>
Spin up a practice project:
$ mix phx.new myapp --no-ecto
Now go into myapp/lib/myapp_web/templates/page/index.html.eex
and add the target <pre>
element:
<div class="jumbotron">
<h2><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h2>
<p class="lead">A productive web framework that<br />does not compromise speed and maintainability.</p>
</div>
<!-- BEGIN: add this -->
<div>
<pre id="displayArea"></pre>
</div>
<!-- END add this -->
<div class="row marketing">
To make things a bit more interesting - in myapp/assets/js
create a new file my-module.js
(learn more and then some):
// file: myapp/assets/js/my-module.js
// https://github.com/lodash/lodash/wiki/FP-Guide
import _ from "lodash/fp"; // Note "_" is now a local variable
// inside the module - NOT a global
export default _.filter(
_.flow(
_.get('name'),
_.isEqual('bar')
)
); // i.e. this module exports exactly one function
Now to the end of app.js
already found in myapp/assets/js
append some code:
...
// to also remove its path from "config.paths.watched".
import "phoenix_html"
// Import local files
//
// Local files can be imported directly using relative
// paths "./socket" or full ones "web/static/js/socket".
// import socket from "./socket"
// BEGIN -- appended code
import getBars from "./my-module"; // i.e. giving the function exported
// by my-module.js the name "getBars"
const displayArea = document.getElementById('displayArea');
const items = [
{name: 'baz'},
{name: 'foo'},
{name: 'bar'},
{name: 'bar'},
{name: 'foo'},
];
displayArea.textContent = JSON.stringify(
getBars(items)
);
// END -- appended code
Make sure your current working directory is myapp
and fire up the phoenix server with:
$ mix phx.server
and point your browser to http://localhost:4000/
. The page will display - but the textContent
of the added <pre>
element is empty - checking the JavaScript console reveals some errors.
At another command prompt ensure that your working directory is myapp/assets
and then issue the following command:
$ npm i lodash
At this point the phoenix page should reload and you should finally see
[{"name":"bar"},{"name":"bar"}]
in the added <pre>
element.
Bonus: in myapp/assets/js/app.js
you may have noticed
import "phoenix_html"
Now just like lodash
it comes from myapp/assets/node_modules
- but not exactly. Looking at myapp/assets/node_modules/phoenix_html
it becomes clear that it’s a link rather than a folder and looking at myapp/assets/package.json
it becomes clear why npm
created it:
...
},
"dependencies": {
"lodash": "^4.17.4",
"phoenix": "file:../deps/phoenix",
"phoenix_html": "file:../deps/phoenix_html"
},
"devDependencies": {
...
myapp/deps/phoenix_html
contains among other things a package.json
:
{
"name": "phoenix_html",
"version": "2.10.4",
"main": "./priv/static/phoenix_html.js",
"repository": {
},
"files": ["LICENSE.md", "package.json", "priv/static/phoenix_html.js"]
}
which essentially tells npm
to use myapp/deps/phoenix_html/priv/static/phoenix_html.js
.
So in this roundabout way
import "phoenix_html"
actually imports myapp/deps/phoenix_html/priv/static/phoenix_html.js
.
Now be sure to review the Phoenix Static Assets Guide and if you decide to stay with Brunch as the asset management tool to give the Brunch Guide a good look (better yet, work through it). That being said Phoenix can be adapted to other tools.