supnate / rekit

IDE and toolkit for building scalable web applications with React, Redux and React-router
http://rekit.js.org
MIT License
4.48k stars 258 forks source link

Does Rekit support Webpack 4? #131

Open Nantris opened 6 years ago

Nantris commented 6 years ago

I'm looking at potentially moving to Rekit, but I'm wondering if it supports Webpack 4 which is what I'm currently using, or if this doesn't matter? Thanks very much Nate!

Thebarda commented 6 years ago

Rekit doesn't support webpack 4 but you can upgrade your package.json to webpack 4. I did it in my own project. Rekit is very configurable and it's a strong point ;)

ianitsky commented 5 years ago

@Thebarda Do you have the diff of the webpack config?

Thank you

Thebarda commented 5 years ago

@ianitsky Ouch.... Rekit had a lot of updates and I did not use it since June 2018. Furthermore, I deleted the project from my disk (it was a test project ;))

If you want, I can re-create a test project and retry to works with webpack 4 :)

Nantris commented 5 years ago

I'm using Webpack 4 and it works.

Thebarda commented 5 years ago

@ianitsky Here is the new webpack.dev.config.js :

const autoprefixer = require('autoprefixer');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const eslintFormatter = require('react-dev-utils/eslintFormatter');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getClientEnvironment = require('./env');
const paths = require('./paths');

const publicPath = '/';
const publicUrl = '';
const env = getClientEnvironment(publicUrl);

module.exports = {
  mode: 'development',
  devtool: 'cheap-module-source-map',
  entry: [
    // We ship a few polyfills by default:
    require.resolve('./polyfills'),
    require.resolve('react-dev-utils/webpackHotDevClient'),
    paths.appIndexJs,
    paths.appIndexStyle,
  ],
  output: {
    pathinfo: true,
    filename: 'static/js/bundle.js',
    chunkFilename: 'static/js/[name].chunk.js',
    publicPath: publicPath,
    devtoolModuleFilenameTemplate: info =>
      path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
  },
  resolve: {
    modules: ['node_modules', paths.appNodeModules].concat(
      process.env.NODE_PATH.split(path.delimiter).filter(Boolean),
    ),
    extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
    alias: {
      'react-native': 'react-native-web',
    },
    plugins: [new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson])],
  },
  module: {
    strictExportPresence: true,
    rules: [
      {
        test: /\.(js|jsx|mjs)$/,
        enforce: 'pre',
        use: [
          {
            options: {
              formatter: eslintFormatter,
              eslintPath: require.resolve('eslint'),
            },
            loader: require.resolve('eslint-loader'),
          },
        ],
        include: paths.appSrc,
      },
      {
        oneOf: [
          {
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            loader: require.resolve('url-loader'),
            options: {
              limit: 10000,
              name: 'static/media/[name].[hash:8].[ext]',
            },
          },
          {
            test: /\.(js|jsx|mjs)$/,
            include: paths.appSrc,
            loader: require.resolve('babel-loader'),
            options: {
              cacheDirectory: true,
            },
          },
          {
            test: /\.less$/,
            loader: 'style-loader!css-loader?sourceMap!less-loader?sourceMap',
          },
          {
            test: /\.css$/,
            use: [
              require.resolve('style-loader'),
              {
                loader: require.resolve('css-loader'),
                options: {
                  importLoaders: 1,
                },
              },
              {
                loader: require.resolve('postcss-loader'),
                options: {
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-flexbugs-fixes'),
                    autoprefixer({
                      browsers: ['>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 9'],
                      flexbox: 'no-2009',
                    }),
                  ],
                },
              },
            ],
          },
          {
            exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
            loader: require.resolve('file-loader'),
            options: {
              name: 'static/media/[name].[hash:8].[ext]',
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      inject: true,
      template: paths.appHtml,
    }),
    new webpack.HotModuleReplacementPlugin(),
    new CaseSensitivePathsPlugin(),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
  ],
  node: {
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty',
  },
  performance: {
    hints: false,
  },
};

And the new webpack.prod.config.js :

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
const eslintFormatter = require('react-dev-utils/eslintFormatter');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const paths = require('./paths');
const getClientEnvironment = require('./env');

const publicPath = paths.servedPath;
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
const publicUrl = publicPath.slice(0, -1);
const env = getClientEnvironment(publicUrl);

if (env.stringified['process.env'].NODE_ENV !== '"production"') {
  throw new Error('Production builds must have NODE_ENV=production.');
}

module.exports = {
  mode: 'production',
  bail: true,
  devtool: shouldUseSourceMap ? 'source-map' : false,
  entry: [require.resolve('./polyfills'), paths.appIndexJs, paths.appIndexStyle],
  output: {
    path: paths.appBuild,
    filename: 'static/js/[name].[chunkhash:8].js',
    chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
    publicPath: publicPath,
    devtoolModuleFilenameTemplate: info =>
      path.relative(paths.appSrc, info.absoluteResourcePath).replace(/\\/g, '/'),
  },
  resolve: {
    modules: ['node_modules', paths.appNodeModules].concat(
      process.env.NODE_PATH.split(path.delimiter).filter(Boolean),
    ),
    extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
    alias: {
      'react-native': 'react-native-web',
    },
    plugins: [new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson])],
  },
  module: {
    strictExportPresence: true,
    rules: [
      {
        test: /\.(js|jsx|mjs)$/,
        enforce: 'pre',
        use: [
          {
            options: {
              formatter: eslintFormatter,
              eslintPath: require.resolve('eslint'),
            },
            loader: require.resolve('eslint-loader'),
          },
        ],
        include: paths.appSrc,
      },
      {
        oneOf: [
          {
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            loader: require.resolve('url-loader'),
            options: {
              limit: 10000,
              name: 'static/media/[name].[hash:8].[ext]',
            },
          },
          {
            test: /\.(js|jsx|mjs)$/,
            include: paths.appSrc,
            loader: require.resolve('babel-loader'),
            options: {
              compact: true,
            },
          },
          {
            test: /\.less$/,
            loader: 'style-loader!css-loader!less-loader',
          },
          {
            test: /\.(sa|sc|c)ss$/,
            use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader'],
          },
          {
            loader: require.resolve('file-loader'),
            exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
            options: {
              name: 'static/media/[name].[hash:8].[ext]',
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      inject: true,
      template: paths.appHtml,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true,
      },
    }),
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
    new ManifestPlugin({
      fileName: 'asset-manifest.json',
    }),
    new SWPrecacheWebpackPlugin({
      dontCacheBustUrlsMatching: /\.\w{8}\./,
      filename: 'service-worker.js',
      logger(message) {
        if (message.indexOf('Total precache size is') === 0) {
          return;
        }
        if (message.indexOf('Skipping static resource') === 0) {
          return;
        }
        console.log(message);
      },
      minify: true,
      navigateFallback: publicUrl + '/index.html',
      navigateFallbackWhitelist: [/^(?!\/__).*/],
      staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
  ],
  node: {
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty',
  },
};

webpackDevServer.config.js doesn't change.

You have to update webpack, webpack-dev-server, webpack-manifest-plugin, url-loader, style-loader, postcss-loader, less-loader, file-loader, eslint-loader, css-loader, html-webpack-plugin to last version.

Finally, you have to install mini-css-extract-plugin

So I did it very quckly, I am convinced you can optimize thoses webpack config files.

I hope it will help you :)

ianitsky commented 5 years ago

Thanks @Thebarda . It's worked.

Have only a little issue, but I can fix it:

GET http://192.168.0.155:5000/%PUBLIC_URL%/favicon.ico 400 (Bad Request)

And if I do modifications, I'll post here.

Thebarda commented 5 years ago

@ianitsky Yeah, just replace %PUBLIC_URL% by ./ it should work. It is not an important issue but it good to resolve it ;)

zedtux commented 5 years ago

Thank you @Thebarda it seem to work but the app is not working with the following error :

TypeError: undefined is not an object (evaluating '_this.store.dispatch')
handleLocationChange
node_modules/react-router-redux/es/ConnectedRouter.js:26
  23 | }
  24 | 
  25 | return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.handleLocationChange = function (location) {
> 26 |   _this.store.dispatch({
     | ^  27 |     type: LOCATION_CHANGE,
  28 |     payload: location
  29 |   });
...

I have already opened an issue about this deprecated react-router-redux but there's no update on this.

Why is this failing in my project and not in yours ?

Thebarda commented 5 years ago

I'll check my package-lock.json

zedtux commented 5 years ago

Thank you @Thebarda

Thebarda commented 5 years ago

I got this :

"react-router-redux": {
      "version": "5.0.0-alpha.9",
      "resolved": "https://registry.npmjs.org/react-router-redux/-/react-router-redux-5.0.0-alpha.9.tgz",
      "integrity": "sha512-euSgNIANnRXr4GydIuwA7RZCefrLQzIw5WdXspS8NPYbV+FxrKSS9MKG7U9vb6vsKHONnA4VxrVNWfnMUnUQAw==",
      "requires": {
        "history": "^4.7.2",
        "prop-types": "^15.6.0",
        "react-router": "^4.2.0"
      }
    },
socks4penguins commented 5 years ago

I have been using rekit with webpack 4 for a while now, and all of a sudden I am getting the error when running start SyntaxError: Unexpected token ).

I think its a babel thing, something got updated and I dont know what

here is my package.json

` { "name": "hotelbuddy.online", "version": "0.1.0", "private": true, "dependencies": { "autoprefixer": "7.1.6", "axios": "^0.18.0", "babel-core": "6.26.0", "babel-eslint": "7.2.3", "babel-jest": "20.0.3", "babel-loader": "7.1.2", "babel-plugin-lodash": "^3.3.2", "babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-preset-react-app": "^3.1.1", "babel-runtime": "6.26.0", "case-sensitive-paths-webpack-plugin": "2.1.1", "chalk": "^1.1.3", "css-loader": "^2.1.1", "dotenv": "4.0.0", "dotenv-expand": "4.2.0", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", "eslint": "^4.10.0", "eslint-config-react-app": "^2.1.0", "eslint-loader": "^2.1.2", "eslint-plugin-flowtype": "2.39.1", "eslint-plugin-import": "2.8.0", "eslint-plugin-jsx-a11y": "5.1.1", "eslaint-plugin-react": "7.4.0", "express-history-api-fallback": "^2.2.1", "extract-text-webpack-plugin": "3.0.2", "file-loader": "^3.0.1", "fs-extra": "3.0.1", "html-webpack-plugin": "^3.2.0", "jest": "20.0.4", "less": "^3.9.0", "less-loader": "^4.1.0", "lodash": "^4.17.5", "mini-css-extract-plugin": "^0.6.0", "nock": "^9.2.3", "object-assign": "4.1.1", "postcss-flexbugs-fixes": "3.2.0", "postcss-loader": "^3.0.0", "promise": "8.0.1", "raf": "3.4.0", "react": "^16.2.0", "react-dev-utils": "^5.0.3", "react-dom": "^16.2.0", "react-hot-loader": "^4.0.0", "react-redux": "^5.0.7", "react-router-dom": "^4.2.2", "react-router-redux": "5.0.0-alpha.9", "redux": "^3.7.2", "redux-logger": "^3.0.6", "redux-mock-store": "^1.5.1", "redux-thunk": "^2.2.0", "rekit-core": "^2.3.0", "rekit-studio": "^2.3.0", "style-loader": "^0.23.1", "sw-precache-webpack-plugin": "0.11.4", "url-loader": "^1.1.2", "webpack": "^4.30.0", "webpack-dev-server": "^3.3.1", "webpack-manifest-plugin": "^2.0.4", "whatwg-fetch": "2.0.3" }, "scripts": { "start": "node scripts/start.js", "build": "node scripts/build.js", "test": "node scripts/test.js --env=jsdom" }, "rekit": { "devPort": 6075, "studioPort": 6076, "plugins": [], "css": "less" }, "jest": { "collectCoverageFrom": [ "src/*/.{js,jsx,mjs}" ], "setupFiles": [ "/config/polyfills.js", "/tests/setup.js" ], "testMatch": [ "/tests/*/.test.{js,jsx,mjs}" ], "testEnvironment": "node", "testURL": "http://localhost", "transform": { "^.+\.(js|jsx|mjs)$": "/node_modules/babel-jest", "^.+\.css$": "/config/jest/cssTransform.js", "^(?!.*\.(js|jsx|mjs|css|json)$)": "/config/jest/fileTransform.js" }, "transformIgnorePatterns": [ "[/\\]node_modules[/\\].+\.(js|jsx|mjs)$" ], "moduleNameMapper": { "^react-native$": "react-native-web" }, "moduleFileExtensions": [ "web.js", "mjs", "js", "json", "web.jsx", "jsx", "node" ] }, "eslintConfig": { "extends": "react-app" }, "description": "hotelbuddy.online created by Rekit." }

`

danielo515 commented 4 years ago

I think one key thing is to include the env variables. The posted webpack files do not include that. It is as simple as adding this to the first position on the array of plugins:

new webpack.EnvironmentPlugin(env.raw),
danielo515 commented 4 years ago

If anyone wants a complete upgrade to webpack 4, latest eslint and babel, here is my merge request to myself: https://github.com/danielo515/pento-tech-challenge/pull/33/files