intial version of elm+webpack setup
This commit is contained in:
parent
5bccd8c0b2
commit
8077030139
33
.gitignore
vendored
Normal file
33
.gitignore
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
.idea
|
||||
.cache
|
||||
npm-debug.log*
|
||||
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directory
|
||||
node_modules
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
yarn.lock
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# elm-package generated files
|
||||
elm-stuff/
|
||||
# elm-repl generated files
|
||||
repl-temp-*
|
||||
|
||||
.DS_Store
|
||||
example/dist
|
||||
|
||||
ignore
|
||||
dist
|
||||
tests/VerifyExamples
|
||||
package-lock.json
|
25
default.nix
Normal file
25
default.nix
Normal file
|
@ -0,0 +1,25 @@
|
|||
{ pkgs ? import <nixpkgs> {}
|
||||
}:
|
||||
|
||||
let
|
||||
in pkgs.stdenv.mkDerivation {
|
||||
name = "nixos-search";
|
||||
src = pkgs.lib.cleanSource ./.;
|
||||
|
||||
buildInputs =
|
||||
(with pkgs; [
|
||||
nodejs
|
||||
]) ++
|
||||
(with pkgs.nodePackages; [
|
||||
yarn
|
||||
]) ++
|
||||
(with pkgs.elmPackages; [
|
||||
elm
|
||||
elm-format
|
||||
]);
|
||||
|
||||
shellHook = ''
|
||||
export PATH=$PWD/node_modules/.bin:$PATH
|
||||
'';
|
||||
|
||||
}
|
31
elm.json
Normal file
31
elm.json
Normal file
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"type": "application",
|
||||
"source-directories": [
|
||||
"src"
|
||||
],
|
||||
"elm-version": "0.19.1",
|
||||
"dependencies": {
|
||||
"direct": {
|
||||
"elm/browser": "1.0.2",
|
||||
"elm/core": "1.0.4",
|
||||
"elm/html": "1.0.0",
|
||||
"elm/http": "2.0.0",
|
||||
"elm/json": "1.1.3",
|
||||
"elm/url": "1.0.0"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/bytes": "1.0.8",
|
||||
"elm/file": "1.0.5",
|
||||
"elm/time": "1.0.0",
|
||||
"elm/virtual-dom": "1.0.2"
|
||||
}
|
||||
},
|
||||
"test-dependencies": {
|
||||
"direct": {
|
||||
"elm-explorations/test": "1.2.2"
|
||||
},
|
||||
"indirect": {
|
||||
"elm/random": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
45
package.json
Normal file
45
package.json
Normal file
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "nixos-search",
|
||||
"version": "1.0.0",
|
||||
"description": "Search NixOS packages and options.",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/NixOS/nixos-search",
|
||||
"author": "Rok Garbas <rok@garbas.si>",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "elm-test",
|
||||
"dev": "webpack-dev-server --hot --colors --port 3000",
|
||||
"build": "webpack",
|
||||
"prod": "webpack -p",
|
||||
"analyse": "elm-analyse -s -p 3001 -o"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.2",
|
||||
"@babel/preset-env": "^7.7.1",
|
||||
"babel-loader": "^8.0.6",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"closure-webpack-plugin": "^2.0.1",
|
||||
"copy-webpack-plugin": "^5.0.5",
|
||||
"css-loader": "^3.2.0",
|
||||
"elm-analyse": "^0.16.5",
|
||||
"elm-hot-webpack-loader": "^1.1.6",
|
||||
"elm-test": "^0.19.1-1",
|
||||
"elm-webpack-loader": "^6.0.1",
|
||||
"file-loader": "^6.0.0",
|
||||
"google-closure-compiler": "^20200224.0.0",
|
||||
"html-webpack-plugin": "^4.0.2",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"node-sass": "^4.13.1",
|
||||
"resolve-url-loader": "^3.1.0",
|
||||
"sass-loader": "^8.0.0",
|
||||
"style-loader": "^1.0.0",
|
||||
"url-loader": "^4.0.0",
|
||||
"webpack": "^4.41.2",
|
||||
"webpack-cli": "^3.3.10",
|
||||
"webpack-dev-server": "^3.9.0",
|
||||
"webpack-merge": "^4.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"purecss": "^1.0.1"
|
||||
}
|
||||
}
|
|
@ -27,13 +27,16 @@ def get_last_evaluation(channel):
|
|||
)
|
||||
evaluations = []
|
||||
for item in s3_result.get("CommonPrefixes"):
|
||||
if not item :
|
||||
if not item:
|
||||
continue
|
||||
prefix = item.get("Prefix")
|
||||
evaluation = prefix[len(f"{project}/{project_version}/{channel}"):]
|
||||
if evaluation.startswith("beta"):
|
||||
evaluation = evaluation[len("beta"):]
|
||||
revisions_since_start, git_revision = evaluation.lstrip(".").rstrip("/").split(".")
|
||||
try:
|
||||
revisions_since_start, git_revision = evaluation.lstrip(".").rstrip("/").split(".")
|
||||
except:
|
||||
continue
|
||||
evaluations.append(dict(
|
||||
revisions_since_start=int(revisions_since_start),
|
||||
git_revision=git_revision,
|
||||
|
|
216
src/Main.elm
Normal file
216
src/Main.elm
Normal file
|
@ -0,0 +1,216 @@
|
|||
port module Main exposing (main)
|
||||
|
||||
import Browser exposing (UrlRequest(..))
|
||||
import Browser.Navigation as Nav exposing (Key)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick)
|
||||
import Http exposing (Error(..))
|
||||
import Json.Decode as Decode
|
||||
import Url exposing (Url)
|
||||
import Url.Parser as UrlParser exposing ((</>), Parser)
|
||||
|
||||
|
||||
|
||||
-- ---------------------------
|
||||
-- PORTS
|
||||
-- ---------------------------
|
||||
|
||||
|
||||
port toJs : String -> Cmd msg
|
||||
|
||||
|
||||
|
||||
-- ---------------------------
|
||||
-- MODEL
|
||||
-- ---------------------------
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ key : Key
|
||||
, page : Page
|
||||
}
|
||||
|
||||
|
||||
init : Int -> Url -> Key -> ( Model, Cmd Msg )
|
||||
init flags url key =
|
||||
( { key = key, page = UrlParser.parse urlParser url |> Maybe.withDefault (Counter 0) }, Cmd.none )
|
||||
|
||||
|
||||
type Page
|
||||
= Counter Int
|
||||
| Server String
|
||||
|
||||
|
||||
|
||||
-- ---------------------------
|
||||
-- URL Parsing and Routing
|
||||
-- ---------------------------
|
||||
|
||||
|
||||
handleUrlRequest : Key -> UrlRequest -> Cmd msg
|
||||
handleUrlRequest key urlRequest =
|
||||
case urlRequest of
|
||||
Internal url ->
|
||||
Nav.pushUrl key (Url.toString url)
|
||||
|
||||
External url ->
|
||||
Nav.load url
|
||||
|
||||
|
||||
urlParser : Parser (Page -> msg) msg
|
||||
urlParser =
|
||||
UrlParser.oneOf
|
||||
[ UrlParser.map Counter <| UrlParser.s "counter" </> UrlParser.int
|
||||
, UrlParser.map Server <| UrlParser.s "server" </> UrlParser.string
|
||||
, UrlParser.map (Server "") <| UrlParser.s "server"
|
||||
]
|
||||
|
||||
|
||||
|
||||
-- ---------------------------
|
||||
-- UPDATE
|
||||
-- ---------------------------
|
||||
|
||||
|
||||
type Msg
|
||||
= OnUrlRequest UrlRequest
|
||||
| OnUrlChange Url
|
||||
| Inc
|
||||
| TestServer
|
||||
| OnServerResponse (Result Http.Error String)
|
||||
|
||||
|
||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||
update message model =
|
||||
case message of
|
||||
OnUrlRequest urlRequest ->
|
||||
( model, handleUrlRequest model.key urlRequest )
|
||||
|
||||
OnUrlChange url ->
|
||||
( { model | page = UrlParser.parse urlParser url |> Maybe.withDefault model.page }, Cmd.none )
|
||||
|
||||
Inc ->
|
||||
case model.page of
|
||||
Counter x ->
|
||||
let
|
||||
xx =
|
||||
x + 1
|
||||
in
|
||||
( { model | page = Counter xx }
|
||||
, Nav.pushUrl model.key <| "/counter/" ++ String.fromInt xx
|
||||
)
|
||||
|
||||
_ ->
|
||||
( model, Cmd.none )
|
||||
|
||||
TestServer ->
|
||||
let
|
||||
expect =
|
||||
Http.expectJson OnServerResponse (Decode.field "result" Decode.string)
|
||||
in
|
||||
( model
|
||||
, Http.get { url = "/test", expect = expect }
|
||||
)
|
||||
|
||||
OnServerResponse res ->
|
||||
case res of
|
||||
Ok serverMessage ->
|
||||
( { model | page = Server serverMessage }, Cmd.none )
|
||||
|
||||
Err err ->
|
||||
( { model | page = Server <| "Error: " ++ httpErrorToString err }, Cmd.none )
|
||||
|
||||
|
||||
httpErrorToString : Http.Error -> String
|
||||
httpErrorToString err =
|
||||
case err of
|
||||
BadUrl _ ->
|
||||
"BadUrl"
|
||||
|
||||
Timeout ->
|
||||
"Timeout"
|
||||
|
||||
NetworkError ->
|
||||
"NetworkError"
|
||||
|
||||
BadStatus _ ->
|
||||
"BadStatus"
|
||||
|
||||
BadBody s ->
|
||||
"BadBody: " ++ s
|
||||
|
||||
|
||||
|
||||
-- ---------------------------
|
||||
-- VIEW
|
||||
-- ---------------------------
|
||||
|
||||
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
div [ class "container" ]
|
||||
[ header []
|
||||
[ img [ src "/images/logo.png" ] []
|
||||
, h1 [] [ text "Elm 0.19 Webpack Starter, with hot-reloading" ]
|
||||
]
|
||||
, case model.page of
|
||||
Counter counter ->
|
||||
counterPage counter
|
||||
|
||||
Server serverMessage ->
|
||||
serverPage serverMessage
|
||||
, p []
|
||||
[ text "And now don't forget to add a star to the Github repo "
|
||||
, a [ href "https://github.com/simonh1000/elm-webpack-starter" ] [ text "elm-webpack-starter" ]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
counterPage counter =
|
||||
div [ class "pure-u-1-3" ]
|
||||
[ a [ href "/server/" ] [ text "Switch to server" ]
|
||||
, p [] [ text "Click on the button below to increment the state." ]
|
||||
, button
|
||||
[ class "pure-button pure-button-primary"
|
||||
, onClick Inc
|
||||
]
|
||||
[ text "+ 1" ]
|
||||
, text <| String.fromInt counter
|
||||
, p [] [ text "Then make a change to the source code and see how the state is retained after you recompile." ]
|
||||
]
|
||||
|
||||
|
||||
serverPage serverMessage =
|
||||
div [ class "pure-u-1-3" ]
|
||||
[ a [ href "/counter/1" ] [ text "Switch to counter" ]
|
||||
, p [] [ text "Test the dev server" ]
|
||||
, button
|
||||
[ class "pure-button pure-button-primary"
|
||||
, onClick TestServer
|
||||
]
|
||||
[ text "ping dev server" ]
|
||||
, text serverMessage
|
||||
]
|
||||
|
||||
|
||||
|
||||
-- ---------------------------
|
||||
-- MAIN
|
||||
-- ---------------------------
|
||||
|
||||
|
||||
main : Program Int Model Msg
|
||||
main =
|
||||
Browser.application
|
||||
{ init = init
|
||||
, update = update
|
||||
, view =
|
||||
\m ->
|
||||
{ title = "Elm 0.19 starter"
|
||||
, body = [ view m ]
|
||||
}
|
||||
, subscriptions = \_ -> Sub.none
|
||||
, onUrlRequest = OnUrlRequest
|
||||
, onUrlChange = OnUrlChange
|
||||
}
|
0
src/assets/.gitkeep
Normal file
0
src/assets/.gitkeep
Normal file
0
src/assets/images/.gitkeep
Normal file
0
src/assets/images/.gitkeep
Normal file
BIN
src/assets/images/logo.png
Normal file
BIN
src/assets/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
11
src/index.html
Normal file
11
src/index.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Elm hotloading dev environment</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
15
src/index.js
Normal file
15
src/index.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
'use strict';
|
||||
|
||||
require("./styles.scss");
|
||||
|
||||
const {Elm} = require('./Main');
|
||||
var app = Elm.Main.init({flags: 6});
|
||||
|
||||
app.ports.toJs.subscribe(data => {
|
||||
console.log(data);
|
||||
})
|
||||
// Use ES2015 syntax and let Babel compile it for you
|
||||
var testFn = (inp) => {
|
||||
let a = inp + 1;
|
||||
return a;
|
||||
}
|
30
src/styles.scss
Normal file
30
src/styles.scss
Normal file
|
@ -0,0 +1,30 @@
|
|||
@import '~purecss/build/pure.css';
|
||||
|
||||
body {
|
||||
background-color: #ddd;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
img {
|
||||
width: 60px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
background: url('images/logo.png');
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background-size: cover;
|
||||
}
|
52
tests/Example.elm
Normal file
52
tests/Example.elm
Normal file
|
@ -0,0 +1,52 @@
|
|||
module Example exposing (fuzzTest, unitTest, viewTest)
|
||||
|
||||
import Expect exposing (Expectation)
|
||||
import Fuzz exposing (Fuzzer, int, list, string)
|
||||
import Main exposing (..)
|
||||
import Test exposing (..)
|
||||
import Test.Html.Query as Query
|
||||
import Test.Html.Selector exposing (tag, text)
|
||||
|
||||
|
||||
{-| See <https://github.com/elm-community/elm-test>
|
||||
-}
|
||||
unitTest : Test
|
||||
unitTest =
|
||||
describe "simple unit test"
|
||||
[ test "Inc adds one" <|
|
||||
\() ->
|
||||
update Inc (Model 0 "")
|
||||
|> Tuple.first
|
||||
|> .counter
|
||||
|> Expect.equal 1
|
||||
]
|
||||
|
||||
|
||||
{-| See <https://github.com/elm-community/elm-test>
|
||||
-}
|
||||
fuzzTest : Test
|
||||
fuzzTest =
|
||||
describe "simple fuzz test"
|
||||
[ fuzz int "Inc ALWAYS adds one" <|
|
||||
\ct ->
|
||||
update Inc (Model ct "")
|
||||
|> Tuple.first
|
||||
|> .counter
|
||||
|> Expect.equal (ct + 1)
|
||||
]
|
||||
|
||||
|
||||
{-| see <https://github.com/eeue56/elm-html-test>
|
||||
-}
|
||||
viewTest : Test
|
||||
viewTest =
|
||||
describe "Testing view function"
|
||||
[ test "Button has the expected text" <|
|
||||
\() ->
|
||||
Model 0 ""
|
||||
|> view
|
||||
|> Query.fromHtml
|
||||
|> Query.findAll [ tag "button" ]
|
||||
|> Query.first
|
||||
|> Query.has [ text "+ 1" ]
|
||||
]
|
185
webpack.config.js
Normal file
185
webpack.config.js
Normal file
|
@ -0,0 +1,185 @@
|
|||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const merge = require("webpack-merge");
|
||||
|
||||
const ClosurePlugin = require('closure-webpack-plugin');
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const HTMLWebpackPlugin = require("html-webpack-plugin");
|
||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||
// to extract the css as a separate file
|
||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||
|
||||
var MODE =
|
||||
process.env.npm_lifecycle_event === "prod" ? "production" : "development";
|
||||
var withDebug = !process.env["npm_config_nodebug"] && MODE == "development";
|
||||
// this may help for Yarn users
|
||||
// var withDebug = !npmParams.includes("--nodebug");
|
||||
console.log('\x1b[36m%s\x1b[0m', `** elm-webpack-starter: mode "${MODE}", withDebug: ${withDebug}\n`);
|
||||
|
||||
var common = {
|
||||
mode: MODE,
|
||||
entry: "./src/index.js",
|
||||
output: {
|
||||
path: path.join(__dirname, "dist"),
|
||||
publicPath: "/",
|
||||
// FIXME webpack -p automatically adds hash when building for production
|
||||
filename: MODE == "production" ? "[name]-[hash].js" : "index.js"
|
||||
},
|
||||
plugins: [
|
||||
new HTMLWebpackPlugin({
|
||||
// Use this template to get basic responsive meta tags
|
||||
template: "src/index.html",
|
||||
// inject details of output file at end of body
|
||||
inject: "body"
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
modules: [path.join(__dirname, "src"), "node_modules"],
|
||||
extensions: [".js", ".elm", ".scss", ".png"]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: "babel-loader"
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
exclude: [/elm-stuff/, /node_modules/],
|
||||
// see https://github.com/webpack-contrib/css-loader#url
|
||||
loaders: ["style-loader", "css-loader?url=false", "sass-loader"]
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: [/elm-stuff/, /node_modules/],
|
||||
loaders: ["style-loader", "css-loader?url=false"]
|
||||
},
|
||||
{
|
||||
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
||||
exclude: [/elm-stuff/, /node_modules/],
|
||||
loader: "url-loader",
|
||||
options: {
|
||||
limit: 10000,
|
||||
mimetype: "application/font-woff"
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
||||
exclude: [/elm-stuff/, /node_modules/],
|
||||
loader: "file-loader"
|
||||
},
|
||||
{
|
||||
test: /\.(jpe?g|png|gif|svg)$/i,
|
||||
exclude: [/elm-stuff/, /node_modules/],
|
||||
loader: "file-loader"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
if (MODE === "development") {
|
||||
module.exports = merge(common, {
|
||||
plugins: [
|
||||
// Suggested for hot-loading
|
||||
new webpack.NamedModulesPlugin(),
|
||||
// Prevents compilation errors causing the hot loader to lose state
|
||||
new webpack.NoEmitOnErrorsPlugin()
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.elm$/,
|
||||
exclude: [/elm-stuff/, /node_modules/],
|
||||
use: [
|
||||
{ loader: "elm-hot-webpack-loader" },
|
||||
{
|
||||
loader: "elm-webpack-loader",
|
||||
options: {
|
||||
// add Elm's debug overlay to output
|
||||
debug: withDebug,
|
||||
//
|
||||
forceWatch: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
devServer: {
|
||||
inline: true,
|
||||
stats: "errors-only",
|
||||
contentBase: path.join(__dirname, "src/assets"),
|
||||
historyApiFallback: true,
|
||||
// feel free to delete this section if you don't need anything like this
|
||||
before(app) {
|
||||
// on port 3000
|
||||
app.get("/test", function(req, res) {
|
||||
res.json({ result: "OK" });
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (MODE === "production") {
|
||||
module.exports = merge(common, {
|
||||
//optimization: {
|
||||
// minimizer: [
|
||||
// new ClosurePlugin({mode: 'STANDARD'}, {})
|
||||
// ]
|
||||
//},
|
||||
plugins: [
|
||||
// Delete everything from output-path (/dist) and report to user
|
||||
new CleanWebpackPlugin({
|
||||
root: __dirname,
|
||||
exclude: [],
|
||||
verbose: true,
|
||||
dry: false
|
||||
}),
|
||||
// Copy static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: "src/assets"
|
||||
}
|
||||
]),
|
||||
new MiniCssExtractPlugin({
|
||||
// Options similar to the same options in webpackOptions.output
|
||||
// both options are optional
|
||||
filename: "[name]-[hash].css"
|
||||
})
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.elm$/,
|
||||
exclude: [/elm-stuff/, /node_modules/],
|
||||
use: {
|
||||
loader: "elm-webpack-loader",
|
||||
options: {
|
||||
optimize: true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: [/elm-stuff/, /node_modules/],
|
||||
loaders: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
"css-loader?url=false"
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
exclude: [/elm-stuff/, /node_modules/],
|
||||
loaders: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
"css-loader?url=false",
|
||||
"sass-loader"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue