rekit
rekit copied to clipboard
Does Rekit support Webpack 4?
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!
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 ;)
@Thebarda Do you have the diff of the webpack config?
Thank you
@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 :)
I'm using Webpack 4 and it works.
@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 :)
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.
@ianitsky Yeah, just replace %PUBLIC_URL%
by ./
it should work.
It is not an important issue but it good to resolve it ;)
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 ?
I'll check my package-lock.json
Thank you @Thebarda
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"
}
},
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": [ "<rootDir>/config/polyfills.js", "<rootDir>/tests/setup.js" ], "testMatch": [ "<rootDir>/tests//.test.{js,jsx,mjs}" ], "testEnvironment": "node", "testURL": "http://localhost", "transform": { "^.+\.(js|jsx|mjs)$": "<rootDir>/node_modules/babel-jest", "^.+\.css$": "<rootDir>/config/jest/cssTransform.js", "^(?!.\.(js|jsx|mjs|css|json)$)": "<rootDir>/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." }
`
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),
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