├── .editorconfig
├── .gitignore
├── CHANGELOG.md
├── README.md
├── bin
└── hjs-dev-server.js
├── examples
├── assets-and-index-html
│ ├── .babelrc
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── Hello.js
│ │ ├── andyet.png
│ │ ├── andyet.svg
│ │ ├── app.js
│ │ └── styles.styl
│ └── webpack.config.js
├── just-assets-no-html
│ ├── .babelrc
│ ├── README.md
│ ├── bring-your-own.html
│ ├── package.json
│ ├── src
│ │ ├── Hello.js
│ │ ├── app.js
│ │ └── styles.styl
│ └── webpack.config.js
└── prerendered-html-files
│ ├── .babelrc
│ ├── README.md
│ ├── package.json
│ ├── src
│ ├── app.js
│ ├── home-page.js
│ ├── other-page.js
│ └── styles.styl
│ └── webpack.config.js
├── index.js
├── lib
├── base-config.js
├── get-package.js
├── html-plugin.js
├── installed-hot-loaders.js
├── installed-style-loaders.js
└── is-installed.js
├── package.json
└── resources
├── hjs-webpack-localhost.crt
└── hjs-webpack-localhost.key
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = spaces
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | examples/**/public/*
3 | npm-debug.log
4 | package-lock.json
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Changelog
2 |
3 | ### 9.2.0
4 | - Update dependencies to their latest versions, including webpack to version 3 ([#349](https://github.com/HenrikJoreteg/hjs-webpack/pull/349))
5 | - Use UglifyJS directly to make use of a version that supports ES2015 code ([#349](https://github.com/HenrikJoreteg/hjs-webpack/pull/349))
6 |
7 | ### 9.1.0
8 | - Update examples to confirm with new linting rules ([#333](https://github.com/HenrikJoreteg/hjs-webpack/pull/333))
9 | - Add support for using different NODE_ENV values than `production` in production build
10 | ([#332](https://github.com/HenrikJoreteg/hjs-webpack/pull/332))
11 | - Add CORS headers to response on static files served by dev server
12 | ([#242](https://github.com/HenrikJoreteg/hjs-webpack/pull/242))
13 | - Add support for using `postcss.config.js` to configure PostCSS
14 | ([#327](https://github.com/HenrikJoreteg/hjs-webpack/pull/327))
15 |
16 | ### 9.0.0
17 | - Add support for webpack 2. Although there are no differences in the API, this version requires you
18 | to migrate to webpack@^2.2.1. You will also have to update your loader dependencies to their newest majors
19 | as well, as many of them have come out with webpack 2 support.
20 | If you have extended the configuration created by `hjs-webpack`, you will have to migrate those changes as
21 | well. Please have a look at the [official migration guide](https://webpack.js.org/guides/migrating/) for
22 | advice on how to do this.
23 |
24 | ### 8.4.3
25 | - Do not replace all environment variables in production [#296](https://github.com/HenrikJoreteg/hjs-webpack/issues/296)
26 |
27 | ### 8.4.2
28 | - Change how default name and version are specified for [#255](https://github.com/HenrikJoreteg/hjs-webpack/issues/255)
29 |
30 | ### 8.4.1
31 | - Add `compression` to dependencies [#291](https://github.com/HenrikJoreteg/hjs-webpack/issues/291)
32 |
33 | ### 8.4.0
34 | - Add `compression` option to dev server [#240](https://github.com/HenrikJoreteg/hjs-webpack/issues/240)
35 | - Add `pug-loader` to work with `.pug` files (and be backward compatible with `.jade` files) [#271](https://github.com/HenrikJoreteg/hjs-webpack/issues/271)
36 | - Add option to set `devtool` when `isDev` is true [#276](https://github.com/HenrikJoreteg/hjs-webpack/issues/276)
37 | - Use a default `package.name` and `package.version` so it doesn't error without them [#255](https://github.com/HenrikJoreteg/hjs-webpack/issues/255)
38 |
39 | ### 8.3.0
40 | - Add support for `webpack-visualizer-plugin` [#190](https://github.com/HenrikJoreteg/hjs-webpack/issues/190)
41 | - Throw error if trying to clear a directory containing the current working directory [#186](https://github.com/HenrikJoreteg/hjs-webpack/issues/186)
42 | - Allow setting uglifyjs options from config [#81](https://github.com/HenrikJoreteg/hjs-webpack/issues/81)
43 |
44 | ### 8.2.0
45 | - Add file extension `.tsx` to typescript loader [#223](https://github.com/HenrikJoreteg/hjs-webpack/pull/223)
46 | - Update `http-proxy-middleware` [#216](https://github.com/HenrikJoreteg/hjs-webpack/pull/216)
47 |
48 | ### 8.1.0
49 | - Add support for dev server proxies with `http-proxy-middleware` [#198](https://github.com/HenrikJoreteg/hjs-webpack/pull/198)
50 |
51 | ### 8.0.0
52 | Since hot module reloading can be done in many different forms (see [this blog post](https://medium.com/@dan_abramov/hot-reloading-in-react-1140438583bf#.r3jfruhdm) and [this PR](https://github.com/reactjs/redux/pull/1455/files) for more info), `hjs-webpack` no longer looks at which loaders/plugins you have installed to determine if HMR should be turned on or off, and instead only looks at the config option `devServer.hot` to determine if the HMR entry path and plugins should be added to the config.
53 |
54 | By default, HMR has always been set to `true`, but previously if you didn't have a specific set of plugins installed `hjs-webpack` would set it to `false`. This is no longer the case, and is the reason why this is a major update. **If you are not using HMR, then you now need to set `devServer.hot = false` in your config to turn it off.**
55 |
56 | ### 7.3.2
57 | - Update `webpack-hot-middleware` to `^2.8.1`
58 |
59 | ### 7.3.1
60 | - Update dependencies, and pin `webpack-hot-middleware` to `2.7.1` for now to avoid [this issue](https://github.com/glenjamin/webpack-hot-middleware/issues/80)
61 |
62 | ### 7.3.0
63 | - Add option for enabling zoom on mobile devices [#176](https://github.com/HenrikJoreteg/hjs-webpack/issues/176)
64 | - Move `
` followed by the main script tag is also intentional. The ordering ensures we don't have to wait for `DOMReady` in our clientside code, you can safely assume that *both* `document.body` and `document.head` will be available when your script executes.
339 |
340 | If you just want to do JS and CSS and handle all the html yourself, simply add `html: false` to your config (see examples directory for example).
341 |
342 | **using an `html` function to generate specific files**
343 |
344 | This is where it gets interesting. Imagine pre-rendering all known structural content for a Native Web App to static files. Users get pixels on the screen immediately, your JS takes over when downloaded. If you're using React, this "taking over" can be completely seamless and invisible to the user. It's also possible with this approach to write an app that works entirely without JS. See the [prerendered-html-files example](https://github.com/HenrikJoreteg/hjs-webpack/tree/master/examples/prerendered-html-files).
345 |
346 | Your function should produce an object.
347 |
348 | Each key in the object is a filename, and its value is a string to be written to disc.
349 |
350 | If you simply specify `html: true` it will do the following by default:
351 |
352 | ```js
353 | html: function (context) {
354 | return {
355 | 'index.html': context.defaultTemplate()
356 | }
357 | }
358 | ```
359 |
360 | So if you want to produce other files, you can do so by adding them to the returned object:
361 |
362 | ```js
363 | html: function (context) {
364 | return {
365 | 'index.html': context.defaultTemplate(),
366 |
367 | // if you build it entirely yourself it should be a complete HTML document
368 | // using whatever templating system you want
369 | 'other.html': '
Hello World
'
370 | }
371 | }
372 | ```
373 |
374 | **async version**
375 |
376 | ```js
377 | html: function (context, callback) {
378 | // do whatever async stuff generate result object
379 | // and pass it to the callback instead
380 | db.fetchData(function (err, data) {
381 | callback(null, {
382 | 'index.html': buildHTML(data),
383 | 'other.html': doSomethingElse(data)
384 | })
385 | })
386 | }
387 | ```
388 |
389 | **The context argument**
390 |
391 | Your `html` function will be called with a context object that contains the following:
392 |
393 | 1. `context.main`: the name of the generated JS file
394 | 2. `context.css`: the name of the generated CSS file. This only exists if `isDev` is `false`, since in development mode the css bundle is inserted dynamically into the document by the [`style-loader`](https://github.com/webpack/style-loader).
395 | 3. `context.defaultTemplate()` a convenience method you can call to generate the basic HTML shown above. This takes a few options too if you just want to make minor tweaks. If you want to do more, just don't use the default template, generate your own instead. The options are:
396 | - `{html: '
Some custom markup
'}` This markup will be added inside the `` tag. By default it adds a `` as a mount target for React apps.
397 | - `{charset: 'utf-8'}` what charset to set
398 | - `{title: 'your app'}` sets ``
399 | - `{head: 'any string'}` anything else you want to put in the `head`, other meta tags, or whatnot.
400 | - `{metaViewport: boolean|object}` set to false if you don't want the default viewport tag. Set to an object with `userScalable` true if you don't want to block user-zoom on mobile
401 | - `{publicPath: 'http://mycdn.com/'}` (default `/`) pass in path that will prefix the generated css/js files in the template. Note, there is `output.publicPath` provided by webpack, but doesn't easily allow for switching based on envirnoment. In this method we've got access to `context.isDev` and can easily switch based on that.
402 | - `{metaTags: {}}` lets you easily add `` tags to the document head. Takes an object where the key is the `name` and the value is the `content`.
403 | - `{lang: 'en-US'}` sets the `lang` attribute on the `` tag.
404 | 4. `context.isDev`: boolean specifying whether or not we're in dev mode.
405 | 5. `context.package`: the parsed `package.json` file as an object.
406 | 6. `context.stats`: the stats object returned by webpack. Of likely interest is `context.stats.hash` (a hash of current build). `context.stats.assets` is an array of all the assets that will be generated. This can be useful for generating cache manifests, etc. Overall, this is a big object that lists all the modules in your whole app. You likely won't need most of it, but it's all there in case you do. ([A sample can be found here](https://raw.githubusercontent.com/webpack/analyse/master/app/pages/upload/example.json)).
407 |
408 |
409 | ### `serveCustomHtmlInDev` (optional, boolean, default is `true`)
410 |
411 | By default, if you supply an `html` function it will always be used, whether you're in development mode or not.
412 |
413 | Set this option to `false` to only use your `html` function when building for production. Note, that `.isDev` is attached to the context object passed to the `html` function as described above, so alternately you could just use that value to branch your logic within that function. Using this option circumvents the custom `html` function entirely during development.
414 |
415 | ## Proxy
416 |
417 | The dev server uses [http-proxy-middleware](https://www.npmjs.com/package/http-proxy-middleware) to optionally proxy requests to a separate, possibly external, backend server. Proxies can be specified with `devServer.proxy`. This can be a single proxy, or an array of proxies. The proxy context and options are passed directly to `http-proxy-middleware`.
418 |
419 | ```js
420 | getConfig({
421 | in: 'src/app.js',
422 | out: 'public',
423 | clearBeforeBuild: true,
424 |
425 | // Use devServer.proxy to specify proxies
426 | devServer: {
427 | proxy: {
428 | context: "/api",
429 | options: {
430 | target: "http://localhost:3001",
431 | pathRewrite: {
432 | "^/api": ""
433 | }
434 | }
435 | }
436 | }
437 | })
438 | ```
439 |
440 | ## Developing on multiple devices at once
441 |
442 | If you're building an app that you want to look good on all devices it's nice to be able to run them all at once.
443 |
444 | Hotloading makes this extremely nice and convenient.
445 |
446 | If you're on a Mac, this is fairly simple. Just add a `hostname` option to your config like so:
447 |
448 | ```js
449 | module.exports = getConfig({
450 | in: 'src/app.js',
451 | out: 'public',
452 |
453 | // set this to whatever your machine name is
454 | // plus `.local`
455 | // my machine is `loki` so I do:
456 | hostname: 'loki.local'
457 | })
458 | ```
459 |
460 | Now when you run the development instead of going to localhost open: `http://{{yourmachine}}.local:3000` on any device that's on your local network, they should all connect and all hotload your style and JS changes.
461 |
462 | ## Extending `hjs-webpack`
463 |
464 | `hjs-webpack` is not designed to take all the same options as `webpack`. Instead it is designed to take the [config options](#config-options) listed above and return an object that is then consumed by `webpack`. That means that if you want to change/add/remove anything in the config, it is the same as manipulating any JavaScript object.
465 |
466 | Here's an example where `hjs-webpack` is used to create the base `webpack` config, and then it is manipulated to add a new loader, plugin, and option.
467 |
468 | ```js
469 | var webpack = require('webpack')
470 | var getConfig = require('hjs-webpack')
471 | var config = getConfig(myHjsWebpackOptions)
472 |
473 | // Add xml-loader
474 | config.module.rules.push({ test: /\.xml$/, use: ['xml-loader'] })
475 |
476 | // Add webpack PrefetchPlugin
477 | config.plugins.push(new webpack.PrefetchPlugin([context], request))
478 |
479 | // Add a separate entry point for jQuery
480 | config.resolve.alias = { jquery:'jquery/src/jquery.js' }
481 | config.plugins.push(
482 | new webpack.ProvidePlugin({
483 | jQuery: 'jquery',
484 | $: 'jquery',
485 | 'window.jQuery':'jquery'
486 | }),
487 | new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js')
488 | );
489 | config.entry = {
490 | // Add entries for vendors
491 | vendors: ['jquery'],
492 | // Reassign previous single entry to main entry
493 | main: config.entry
494 | };
495 |
496 | // Export the newly manipulated config
497 | module.exports = config
498 | ```
499 |
500 |
501 |
502 | ### Changing Babel config
503 |
504 | Since `hjs-webpack` already has a babel loader, the easiest way to tweak Babel settings is to create a file at the root of your project called `.babelrc` that contains config settings. See [babelrc docs](https://babeljs.io/docs/usage/babelrc/) for more options.
505 |
506 | There are some babel presets that work well with `hjs-webpack`. You can check out an example of using presets in the [examples directory](./examples). There's one with [hot reloading](./examples/assets-and-index-html/.babelrc) and one [without](/examples/just-assets-no-html/.babelrc). You'll need to install these presets just like any other dev dependencies.
507 |
508 | Here's a quick example if you like copy/pasting:
509 |
510 | ```sh
511 | npm install babel-preset-es2015 babel-preset-react babel-preset-react-hmre --save-dev
512 | ```
513 |
514 | and then your `.babelrc`
515 |
516 | ```json
517 | {
518 | "presets": ["es2015", "react"],
519 | "env": {
520 | "development": {
521 | "presets": ["react-hmre"]
522 | }
523 | }
524 | }
525 | ```
526 |
527 |
528 |
529 | ## Credits
530 |
531 | This is mostly just some add-ons to [webpack](http://webpack.github.io/) so most of the credit goes there.
532 |
533 | If you're interested in building apps this way, watch the free section of the tutorials at http://learn.humanjavascript.com. It shows basic usage of this module. Also, you can follow me on twitter [@HenrikJoreteg](http://twitter.com/henrikjoreteg).
534 |
535 | Big thanks to co-maintainer [@LukeKarrys](http://twitter.com/lukekarrys) for helping find/fix some really annoying bugs.
536 |
537 | ## Contributing/Forking
538 |
539 | Beware that this is all highly opinionated and contains a lot of personal preferences. If you want to add or remove major things, feel free to open issues or send PRs, but you may just want to fork it.
540 |
541 | ## Changelog
542 |
543 | See the [`CHANGELOG.md`](CHANGELOG.md)
544 |
545 | ## license
546 |
547 | MIT
548 |
--------------------------------------------------------------------------------
/bin/hjs-dev-server.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | // Based on
4 | // https://github.com/gaearon/react-transform-boilerplate/blob/master/devServer.js
5 |
6 | var fs = require('fs')
7 | var path = require('path')
8 | var express = require('express')
9 | var webpack = require('webpack')
10 | var assign = require('lodash.assign')
11 | var compress = require('compression')
12 | var httpProxyMiddleware = require('http-proxy-middleware')
13 |
14 | var configFile = process.argv[2] || 'webpack.config.js'
15 | var config
16 | try {
17 | config = require(path.join(process.cwd(), configFile))
18 | } catch (e) {
19 | console.error(e.stack)
20 | console.error(
21 | 'Failed to load webpack config, please use like this\n' +
22 | 'hjs-dev-server.js webpack.config.js\n'
23 | )
24 | process.exit(1)
25 | }
26 |
27 | var serverConfig = config.devServer
28 | var https = serverConfig.https
29 | var app = express()
30 |
31 | var createServer = require(https ? 'https' : 'http').createServer
32 | var server
33 |
34 | if (serverConfig.compress) {
35 | app.use(compress())
36 | }
37 |
38 | if (https) {
39 | var httpsConfig = {
40 | key: fs.readFileSync(path.resolve(__dirname, '../resources/hjs-webpack-localhost.key')),
41 | cert: fs.readFileSync(path.resolve(__dirname, '../resources/hjs-webpack-localhost.crt'))
42 | }
43 |
44 | if (typeof https === 'object') {
45 | assign(httpsConfig, https)
46 | }
47 |
48 | server = createServer(httpsConfig, app)
49 | } else {
50 | server = createServer(app)
51 | }
52 |
53 | var compiler = webpack(config)
54 |
55 | if (serverConfig.proxy) {
56 | if (!Array.isArray(serverConfig.proxy)) {
57 | serverConfig.proxy = [serverConfig.proxy]
58 | }
59 | serverConfig.proxy.forEach(function (proxyConfig) {
60 | var proxy = httpProxyMiddleware(proxyConfig.context, proxyConfig.options)
61 | app.use(function (req, res, next) {
62 | next()
63 | }, proxy)
64 | })
65 | }
66 |
67 | if (serverConfig.historyApiFallback) {
68 | app.use(require('connect-history-api-fallback')({
69 | verbose: false
70 | }))
71 | }
72 |
73 | app.use(require('webpack-dev-middleware')(compiler, serverConfig))
74 |
75 | if (serverConfig.hot) {
76 | app.use(require('webpack-hot-middleware')(compiler))
77 | }
78 |
79 | if (serverConfig.contentBase) {
80 | var allowCrossDomain = function (req, res, next) {
81 | res.header('Access-Control-Allow-Origin', '*')
82 | res.header('Access-Control-Allow-Methods', 'GET,OPTIONS')
83 | res.header('Access-Control-Allow-Headers', 'Content-Type')
84 |
85 | next()
86 | }
87 | app.use(allowCrossDomain)
88 | app.use(express.static(serverConfig.contentBase))
89 | }
90 |
91 | server.listen(serverConfig.port, serverConfig.hostname, function (err) {
92 | if (err) {
93 | console.error(err)
94 | return
95 | }
96 |
97 | var protocol = https ? 'https' : 'http'
98 | console.log('Listening at ' + protocol + '://' + serverConfig.hostname + ':' + serverConfig.port)
99 | })
100 |
--------------------------------------------------------------------------------
/examples/assets-and-index-html/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"],
3 | "env": {
4 | "development": {
5 | "presets": ["react-hmre"]
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/examples/assets-and-index-html/README.md:
--------------------------------------------------------------------------------
1 | Simple, catch-all HTML file configuration.
2 |
3 | By default, hjs-webpack will create and serve a catchall HTML file that references your assets.
4 |
5 | ```
6 | var getConfig = require('hjs-webpack')
7 |
8 | module.exports = getConfig({
9 | in: './app.js',
10 | out: 'public',
11 | clearBeforeBuild: true
12 | })
13 | ```
14 |
15 | Try running `npm start` in this folder then opening localhost:3000/something and you'll still see the same HTML response.
16 |
17 | Running `npm run build` will produce a `public` directory with just minified JS, CSS, and a basic `index.html` file that references the built assets.
18 |
--------------------------------------------------------------------------------
/examples/assets-and-index-html/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "assets-and-index-html",
3 | "version": "1.0.0",
4 | "author": "Henrik Joreteg ",
5 | "dependencies": {
6 | "react": "^15.0.1"
7 | },
8 | "devDependencies": {
9 | "autoprefixer": "^6.3.6",
10 | "babel": "^6.5.2",
11 | "babel-core": "^6.7.6",
12 | "babel-loader": "^6.2.4",
13 | "babel-preset-es2015": "^6.6.0",
14 | "babel-preset-react": "^6.5.0",
15 | "babel-preset-react-hmre": "^1.1.1",
16 | "css-loader": "^0.26.4",
17 | "file-loader": "^0.10.1",
18 | "hjs-webpack": "^9.0.0",
19 | "postcss-loader": "^1.3.3",
20 | "react-dom": "^15.0.1",
21 | "style-loader": "^0.13.1",
22 | "stylus": "^0.54.2",
23 | "stylus-loader": "^3.0.1",
24 | "url-loader": "^0.5.7",
25 | "webpack": "^2.2.1",
26 | "yeticss": "^7.3.0"
27 | },
28 | "license": "MIT",
29 | "main": "app.js",
30 | "scripts": {
31 | "start": "hjs-dev-server",
32 | "build": "NODE_ENV=production webpack"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/examples/assets-and-index-html/src/Hello.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | const andyetImgSrc = require('./andyet.png')
3 |
4 | class Hello extends React.Component {
5 | render () {
6 | return (
7 |
8 |
9 |
Assets + HTML Example
10 |
11 |
Generates, base HTML, CSS, and JS on build
12 |
13 |
14 | )
15 | }
16 | }
17 |
18 | export default Hello
19 |
--------------------------------------------------------------------------------
/examples/assets-and-index-html/src/andyet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HenrikJoreteg/hjs-webpack/c8aa76632974819b4882ccceadb7b435725174ca/examples/assets-and-index-html/src/andyet.png
--------------------------------------------------------------------------------
/examples/assets-and-index-html/src/andyet.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/assets-and-index-html/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {render} from 'react-dom'
3 | import Hello from './Hello'
4 |
5 | import './styles.styl'
6 |
7 | render(, document.getElementById('root'))
8 |
--------------------------------------------------------------------------------
/examples/assets-and-index-html/src/styles.styl:
--------------------------------------------------------------------------------
1 | @import 'yeticss'
2 |
3 | body
4 | border: 10px solid $gray-lighter
5 |
6 | header
7 | margin-top: 30px
8 | background-image: url('./andyet.svg')
9 |
--------------------------------------------------------------------------------
/examples/assets-and-index-html/webpack.config.js:
--------------------------------------------------------------------------------
1 | var getConfig = require('hjs-webpack')
2 |
3 | module.exports = getConfig({
4 | in: 'src/app.js',
5 | out: 'public',
6 | clearBeforeBuild: true
7 | })
8 |
--------------------------------------------------------------------------------
/examples/just-assets-no-html/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/examples/just-assets-no-html/README.md:
--------------------------------------------------------------------------------
1 | Simple, no-html configuration
2 |
3 | All you have to do is serve HTML *somehow* that includes the following script tag.
4 |
5 | ```html
6 |
7 | ```
8 |
9 | As long as your `isDev` is true styles and JS should still be hotloaded if possible. Try running `npm start` in this folder then opening `http://localhost:3000/bring-your-own.html` it will serve the `bring-your-own.html` file since it's in the folder here, but running `npm run build` will produce a `public` directory with just minified JS and CSS assets.
10 |
11 | Note that this example has hot module replacement turned off. To turn it on, set `devServer.hot = true` in the webpack config, npm install `babel-preset-react-hmre`, and add this to the `.babelrc`.
12 |
13 | ```
14 | "env": {
15 | "development": {
16 | "presets": ["react-hmre"]
17 | }
18 | }
19 | ```
20 |
--------------------------------------------------------------------------------
/examples/just-assets-no-html/bring-your-own.html:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/examples/just-assets-no-html/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "just-assets-no-html",
3 | "version": "1.0.0",
4 | "author": "Henrik Joreteg ",
5 | "dependencies": {
6 | "react": "^15.0.1"
7 | },
8 | "devDependencies": {
9 | "autoprefixer": "^6.3.6",
10 | "babel": "^6.5.2",
11 | "babel-core": "^6.7.6",
12 | "babel-loader": "^6.2.4",
13 | "babel-preset-es2015": "^6.6.0",
14 | "babel-preset-react": "^6.5.0",
15 | "css-loader": "^0.26.4",
16 | "hjs-webpack": "^9.0.0",
17 | "postcss-loader": "^1.3.3",
18 | "react-dom": "^15.0.1",
19 | "style-loader": "^0.13.1",
20 | "stylus": "^0.54.2",
21 | "stylus-loader": "^3.0.1",
22 | "webpack": "^2.2.1",
23 | "yeticss": "^7.3.0"
24 | },
25 | "license": "MIT",
26 | "main": "app.js",
27 | "scripts": {
28 | "start": "hjs-dev-server",
29 | "build": "NODE_ENV=production webpack"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/examples/just-assets-no-html/src/Hello.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | class Hello extends React.Component {
4 | render () {
5 | return (
6 |
7 |
8 |
Assets Only Example
9 |
10 |
During dev, we just need something to include the script tag:
11 |
<script src="/app.js"></script>
12 |
Building only generates CSS and JS.
13 |
14 | )
15 | }
16 | }
17 |
18 | export default Hello
19 |
--------------------------------------------------------------------------------
/examples/just-assets-no-html/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {render} from 'react-dom'
3 | import Hello from './Hello'
4 |
5 | import './styles.styl'
6 |
7 | render(, document.getElementById('root'))
8 |
--------------------------------------------------------------------------------
/examples/just-assets-no-html/src/styles.styl:
--------------------------------------------------------------------------------
1 | @import 'yeticss'
2 |
3 | body
4 | border: 10px solid $gray-lighter
5 |
6 | header
7 | margin-top: 30px
8 |
--------------------------------------------------------------------------------
/examples/just-assets-no-html/webpack.config.js:
--------------------------------------------------------------------------------
1 | var getConfig = require('hjs-webpack')
2 | var isDev = process.env.NODE_ENV !== 'production'
3 |
4 | module.exports = getConfig({
5 | in: 'src/app.js',
6 | out: 'public',
7 | isDev: isDev,
8 | html: false,
9 | clearBeforeBuild: true,
10 | devServer: {
11 | hot: false,
12 | contentBase: __dirname
13 | }
14 | })
15 |
--------------------------------------------------------------------------------
/examples/prerendered-html-files/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/examples/prerendered-html-files/README.md:
--------------------------------------------------------------------------------
1 | Here we generate multiple static HTML files.
2 |
3 | This can be especially interesting if used to pre-render known HTML with React.
4 |
5 | ```js
6 | var getConfig = require('hjs-webpack')
7 |
8 | module.exports = getConfig({
9 | in: './app.js',
10 | out: 'public',
11 | clearBeforeBuild: true,
12 | html: function (data) {
13 | // here we return an object where each key is a file to be generated
14 | return {
15 | '200.html': data.defaultTemplate(),
16 | 'index.html': [
17 | '',
18 | '',
19 | '',
20 | '',
21 | '',
22 | '
Home Page
',
23 | '',
24 | '',
25 | ''
26 | ].join('')
27 | }
28 | }
29 | })
30 | ```
31 |
32 | **note** it can also be asynchronous and these can be anything (not just HTML strings)
33 |
34 | ```js
35 | html: function (data, cb) {
36 | cb(err, {
37 | 'index.html': '<...>',
38 | 'something.html': '<...>',
39 | 'cache.manifest': '...'
40 | })
41 | }
42 | ```
43 |
44 | ## Start in dev mode
45 |
46 | This just runs the `start` script in the `scripts` section of `package.json`.
47 |
48 | ```
49 | npm start
50 | ```
51 |
52 | In development, this doesn't get used. Instead during dev it just generates a simple default HTML page that includes the assets and is hotloaded, etc.
53 |
54 | ## Build to static
55 |
56 | This just runs the `build` script in the `scripts` section of `package.json`.
57 |
58 | ```
59 | npm run build
60 | ```
61 |
62 | Running `npm run build` will produce a `public` directory with just minified JS, CSS, and a each of the files specified by the HTML callback.
63 |
--------------------------------------------------------------------------------
/examples/prerendered-html-files/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pre-rendered-html",
3 | "version": "1.0.0",
4 | "author": "Henrik Joreteg ",
5 | "dependencies": {
6 | "ampersand-router": "^4.0.0",
7 | "react": "^15.0.1"
8 | },
9 | "devDependencies": {
10 | "autoprefixer": "^6.3.6",
11 | "babel": "^6.5.2",
12 | "babel-core": "^6.7.6",
13 | "babel-loader": "^6.2.4",
14 | "babel-preset-es2015": "^6.6.0",
15 | "babel-preset-react": "^6.5.0",
16 | "babel-preset-react-hmre": "^1.1.1",
17 | "css-loader": "^0.26.4",
18 | "hjs-webpack": "^9.0.0",
19 | "postcss-loader": "^1.3.3",
20 | "react-dom": "^15.0.1",
21 | "style-loader": "^0.13.1",
22 | "stylus": "^0.54.2",
23 | "stylus-loader": "^3.0.1",
24 | "webpack": "^2.2.1",
25 | "yeticss": "^7.3.0"
26 | },
27 | "license": "MIT",
28 | "main": "app.js",
29 | "scripts": {
30 | "start": "hjs-dev-server",
31 | "build": "NODE_ENV=production webpack"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/examples/prerendered-html-files/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {render} from 'react-dom'
3 | import AmpRouter from 'ampersand-router'
4 | import HomePage from './home-page'
5 | import OtherPage from './other-page'
6 |
7 | import './styles.styl'
8 |
9 | const Router = AmpRouter.extend({
10 | routes: {
11 | '': 'home',
12 | 'other': 'other'
13 | },
14 |
15 | home: function () {
16 | render(, document.getElementById('root'))
17 | },
18 |
19 | other: function () {
20 | render(, document.getElementById('root'))
21 | }
22 | })
23 |
24 | let router = new Router()
25 | window.router = router
26 | router.history.start()
27 |
--------------------------------------------------------------------------------
/examples/prerendered-html-files/src/home-page.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | class HomePage extends React.Component {
4 | // quick and dirty internal nav handler
5 | onClick (e) {
6 | e.preventDefault()
7 | window.router.history.navigate('/other')
8 | }
9 | render () {
10 | return (
11 |