Saturday 29 April 2017

How to setup node with webpack dev server?

I want to proxy all /bundle urls to webpack dev server.

I have followed the advice from this question which does the same thing.

However, I still can't see my publicFiles served from localhost:8081/bundle? The silly thing is I have another project not based on react which works just fine, but this just says:

Cannot GET /bundle/

when accessing localhost:8081/bundle .

If you can point out what I'm missing I would really appreciate it. It must be something silly since I know this has to work.

Working in development mode

Here is my webpack config

'use strict';
var webpack = require('webpack');
const autoprefixer = require('autoprefixer');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var CompressionPlugin = require('compression-webpack-plugin');
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
let getPlugins;
var isProd = (process.env.NODE_ENV === 'production');
console.log("Production: " + isProd);

let entryFill = null;
let publicPathFill = null;
if (isProd) {
    entryFill = {
        bootstrap: ['bootstrap/dist/css/bootstrap.css', 'bootstrap/dist/js/bootstrap.js'],
        index: ['./src/bundle/index.tsx'],
        vendor: ['react', 'react-dom', 'jquery', 'jquery-ui-bundle', "redux-thunk", 'redux', 'react-redux']
    }

    publicPathFill = "./dist/assets/bundle";
    getPlugins = function () {
        return [
            new SWPrecacheWebpackPlugin(
                {
                    cacheId: 'cleaning-website',
                    filename: 'service-worker.js',
                    maximumFileSizeToCacheInBytes: 4194304,
                    runtimeCaching: [{
                        handler: 'cacheFirst',
                        urlPattern: /[.]js$/
                    }],
                }
            ),
            new ExtractTextPlugin("site.css"),
            new webpack.optimize.UglifyJsPlugin(),
            new webpack.optimize.OccurrenceOrderPlugin(),
            //new webpack.optimize.DedupePlugin(),
            //new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js'),
            //new webpack.optimize.AggressiveMergingPlugin(),
            new webpack.ProvidePlugin({
                jQuery: 'jquery',
                $: 'jquery',
                jquery: 'jquery'
            })
            //new CompressionPlugin({
            //    asset: "[path].gz[query]",
            //    algorithm: "gzip",
            //    test: /\.js$|\.css$|\.tsx$/,
            //    threshold: 10240,
            //    minRatio: 0.8
            //})
        ]
    }
} else {
    entryFill = {
        bootstrap: ['bootstrap/dist/css/bootstrap.css', 'bootstrap/dist/js/bootstrap.js', 'webpack/hot/dev-server', 'webpack-dev-server/client?http://localhost:8081'],
        index: ['./src/bundle/index.tsx', 'webpack/hot/dev-server', 'webpack-dev-server/client?http://localhost:8081'],
        vendor: ['react', 'react-dom', 'jquery', 'jquery-ui-bundle', "redux-thunk", 'redux', 'react-redux', 'webpack/hot/dev-server', 'webpack-dev-server/client?http://localhost:8081']
    }

    publicPathFill =  "http://localhost:8081/bundle/",
    //publicPathFill = "/",

    getPlugins = function () {
        return [
            new ExtractTextPlugin("site.css"),
            new webpack.HotModuleReplacementPlugin()
        ]
    }

}

module.exports = {
    /**
     * Entry for all client side code.
     * @var {object} entry
     */
    entry: entryFill,
    plugins: getPlugins(),

    output: {
        path: publicPathFill,
        filename: '[name].js',
        libraryTarget: 'umd'
        publicPath: 'http://localhost:8081/bundle/'
    },
    resolve: {
        extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"],
        //alias: {
        //    'react': 'preact-compat',
        //    'react-dom': 'preact-compat',
        //    'react-router': 'preact-compat'
        //}

    },
    module: {
        loaders: [
            //  { test: /\.(jpe?g|png|gif|svg)$/i, loader: 'url?limit=10000!img?progressive=true'},
            { test: /\.css$/, loader: "style-loader!css-loader" },
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract(
                    //Need:?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5] to set the right name for each css!
                    "style",
                    "css!postcss-loader!sass")
            },
            //  { test: /bootstrap-sass\/assets\/javascripts\//, loader: 'imports?jQuery=jquery' },
            { test: /\.tsx?$/, loader: "ts-loader" },
            {
                test: /\.(pug|png|ttf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
                loader: 'file-loader'
            }
        ]
    },
    postcss: function () {
        return [autoprefixer(
            //    { browsers: ['ie 10', 'firefox 20', 'safari 9.1','Chrome ] }
            { browsers: ['> 0%'] }
        )];
    }
};

and my webpack dev server running in node looks like:

import * as express from 'express';
import * as path from 'path'

let webpack = require('webpack');
let WebpackDevServer = require('webpack-dev-server');
let proxy = require('proxy-middleware');
let url = require('url');
let config = require('../../../webpack.config.js');

import { post } from "./post";
import { pages } from "./pages";
module.exports = function (app: any, passport: any) {
    var router = express.Router();
    post(router, passport);
    pages(router);
    if (process.env.NODE_ENV === 'development') {
        let base = path.join(__dirname, "..", "..", "assets");
        console.log("Base : " + base);
        //console.log(__dirname);
        let server = new WebpackDevServer(webpack(config), {
            //contentBase: base,
            hot: true,
            quiet: false,
            noInfo: false,
            publicPath: "/bundle/",

            stats: { colors: true }
        });
        server.listen(8081, "localhost", function () { });
        app.use('/bundle', proxy(url.parse('http://localhost:8081/bundle')));
    }
    app.use('/', router);
};

I serve the html page like so:

import { createStore, bindActionCreators, applyMiddleware } from 'redux';
import { routerReducer } from 'react-router-redux'
import  thunkMiddleware  from 'redux-thunk'
import * as path from 'path'
import * as fs from "fs";
import { Routes, Navigation, RootReducer } from "../../client/index";

export function pages(router) {

    router.get('/*', function (req: any, res: any, next) {
        let initial = {};
        const store = createStore(RootReducer, initial, applyMiddleware(thunkMiddleware))
        const body = ReactDOMServer.renderToString(
            <Provider store={store}>
                <StaticRouter location={req.url}>
                    <Routes/>
                </StaticRouter>
            </Provider>
        )
        //const nav = ReactDOMServer.renderToString(
        //    <Navigation/>
        //)
        const nav = ReactDOMServer.renderToString(
            <div> Nav</div>
        )
        console.log("Body:");
        console.log(body);
        //const state = store.getState()
        const state = {};
        res.send(`
                <!DOCTYPE html>
                <html lang="en">
                <head>
                  <meta charset="UTF-8">
                  <meta name="viewport" content="width=device-width, initial-scale=1">
                  <title>Clement Cleaning</title>
                  <meta name="description" content="A cleaning business">
                  <meta name="author" content="Mortonproductions">
                  <script src="/bundle/bootstrap.js"></script>
                  <link rel="stylesheet" href="/bundle/site.css">
                </head>
                <body>
                  <header>
                    <h1>
                        Clement Cleaning
                    </h1>
                    <h2>
                        A cleaning business based in Loch Lomond
                    </h2>
                  </header>
                  <nav>
                    <div id="react-nav">${nav}</div>
                  </nav>
                  <section>
                    <div id="react-router">${body}</div>
                  </section>
                  <footer>
                     Progressive web app produced my morton productions 
                  </footer>
                  <script>window.__REDUX_STATE__ = ${JSON.stringify(state)}</script>
                  <script src="/bundle/vendor.bundle.js"></script>
                  <script src="/bundle/index.js"></script>
                </body>
                </html>`
        )
    });
}



via mortonprod

No comments:

Post a Comment