Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the install generator to add Webpacker configuration #1404

Merged
merged 41 commits into from Dec 24, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
249590b
Add Webpack configuration files to the template on generator
gscarv13 Oct 23, 2021
a6c31bf
Update hello world component files
gscarv13 Oct 23, 2021
4603396
Update server_bundle_js_file config to server-bundle.js
gscarv13 Oct 23, 2021
1613334
Add methods to copy template files, Add React, TypeScript and CSS mod…
gscarv13 Oct 23, 2021
0cfc67a
Fix Linting issues, Add source reference to each config file
gscarv13 Nov 2, 2021
db358cf
Fix command for adding react dependencies
gscarv13 Nov 7, 2021
801aa18
Update CSS class name
gscarv13 Nov 8, 2021
239328d
Fix conflict between Eslint and Prettier
gscarv13 Nov 9, 2021
4685d54
Remove unnecessary dependencies from the generator
gscarv13 Nov 10, 2021
89ea96b
Add stylesheet_pack_tag to hello_world view
gscarv13 Nov 10, 2021
6af9ca3
Fix Prettier issues from babel and webpack config
gscarv13 Nov 10, 2021
17fc6bd
Add template to add documentation reference
gscarv13 Nov 11, 2021
3e2d24c
Update Procfiles and Documentation
gscarv13 Nov 11, 2021
c87717c
Update Rake task to use webpacker v6, Lock mini_racer to version 0.4.0
gscarv13 Nov 16, 2021
1583b91
Update Webpack config for dummy app
gscarv13 Nov 16, 2021
04902e4
Update dummy app to conform webpacker v6 requirements
gscarv13 Nov 16, 2021
6948f80
Remove test code
gscarv13 Nov 16, 2021
0c711df
Add comments to clarify changes
gscarv13 Nov 17, 2021
d670ee0
Add support for alias path and scss-resources-loader, Remove unused l…
gscarv13 Nov 18, 2021
21da647
Update tutorial.md
gscarv13 Nov 18, 2021
92b49f6
Merge branch 'master' into update-webpacker-config
justin808 Nov 22, 2021
fabd20a
Fix rubocop linting offences
gscarv13 Nov 23, 2021
4ec50ef
Add check for rails version on example generator project task
gscarv13 Nov 23, 2021
5dbf537
Update CHANGELOG and tutorial.md
gscarv13 Nov 23, 2021
01b2ac0
Run webpacker:install to update executables on bin/
gscarv13 Nov 23, 2021
b100880
Update comment about helper generator rake tasks methods
gscarv13 Nov 23, 2021
3e270a5
Update Sass division to use math.div
gscarv13 Dec 8, 2021
3bbdfca
Update Procfile for spec/dummy
gscarv13 Dec 8, 2021
0d8a0e8
Update package.json, Update babel config
gscarv13 Dec 8, 2021
fdd3057
update react-refresh & plugin
Judahmeek Dec 9, 2021
2661c6a
Fix SocketClient is not a constructor error
gscarv13 Dec 9, 2021
6e44563
Run prettier, Update yarn.lock
gscarv13 Dec 14, 2021
9b41c46
Update bin/webpack and bin/webpack-dev-server
gscarv13 Dec 14, 2021
af77c7a
Update .gitignore
gscarv13 Dec 14, 2021
2264499
Remove node_modules folder from the asset load path
gscarv13 Dec 14, 2021
9bc56d7
Update tutorial.md and add link to deployed dummy/app
gscarv13 Dec 15, 2021
f6e96a7
revert whitespace changes
Judahmeek Dec 20, 2021
e502c46
Remove lock from mini_racer, Add comment to tutorial.md
gscarv13 Dec 20, 2021
8e4f0b9
Add comment to bin/yarn, Remove unused variable in development.js
gscarv13 Dec 20, 2021
07e0600
final adjustments
Judahmeek Dec 22, 2021
e6e5063
sync spec/dummy & generator webpacker config
Judahmeek Dec 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .prettierignore
Expand Up @@ -8,3 +8,5 @@ gen-examples/examples/*
node_package/lib/*
spec/react_on_rails/dummy-for-generators/app/javascript/bundles/HelloWorld/*
bundle/
lib/generators/react_on_rails/templates/base/base/config/webpack
lib/generators/react_on_rails/templates/base/base/babel.config.js
42 changes: 42 additions & 0 deletions lib/generators/react_on_rails/base_generator.rb
Expand Up @@ -37,6 +37,35 @@ def copy_base_files
base_files.each { |file| copy_file("#{base_path}#{file}", file) }
end

def copy_js_bundle_files
base_path = "base/base/"
base_files = %w[app/javascript/packs/server-bundle.js
app/javascript/bundles/HelloWorld/components/HelloWorldServer.js
app/javascript/bundles/HelloWorld/components/HelloWorld.module.css]
base_files.each { |file| copy_file("#{base_path}#{file}", file) }
end

def copy_webpack_config
puts "Adding Webpack config"
base_path = "base/base/"
base_files = %w[babel.config.js
config/webpack/clientWebpackConfig.js
config/webpack/commonWebpackConfig.js
config/webpack/development.js
config/webpack/production.js
config/webpack/serverWebpackConfig.js
config/webpack/test.js
config/webpack/webpackConfig.js]
base_files.each { |file| copy_file("#{base_path}#{file}", file) }
end

def copy_webpacker_config
puts "Adding Webpacker v6 config"
base_path = "base/base/"
base_files = %w[config/webpacker.yml]
base_files.each { |file| copy_file("#{base_path}#{file}", file) }
end

def add_base_gems_to_gemfile
gem "mini_racer", platforms: :ruby
run "bundle"
Expand All @@ -51,6 +80,19 @@ def add_yarn_dependencies
puts "Adding the lastest react-on-rails NPM module. Double check this is correct in package.json"
run "yarn add react-on-rails --exact"
end

puts "Adding React dependencies"
run "yarn add react react-dom @babel/preset-react prop-types babel-plugin-transform-react-remove-prop-types \
babel-plugin-macros"

puts "Adding TypeScript dependencies"
run "yarn add typescript @babel/preset-typescript @types/react @types/react-dom"

puts "Adding CSS handlers"
run "yarn add css-loader css-minimizer-webpack-plugin mini-css-extract-plugin style-loader"

puts "Adding dev dependencies"
run "yarn add -D @pmmmwh/react-refresh-webpack-plugin fork-ts-checker-webpack-plugin react-refresh"
end

def append_to_spec_rails_helper
Expand Down
@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import React, { useState } from 'react';
import style from './HelloWorld.module.css';

const HelloWorld = (props) => {
const [name, setName] = useState(props.name);
Expand All @@ -9,7 +10,7 @@ const HelloWorld = (props) => {
<h3>Hello, {name}!</h3>
<hr />
<form>
<label htmlFor="name">
<label className={style.bright} htmlFor="name">
Say hello to:
<input id="name" type="text" value={name} onChange={(e) => setName(e.target.value)} />
</label>
Expand Down
@@ -0,0 +1,4 @@
.bright {
color: green;
font-weight: bold;
}
@@ -0,0 +1,5 @@
import HelloWorld from './HelloWorld';
// This could be specialized for server rendering
// For example, if using React-Router, we'd have the SSR setup here.

export default HelloWorld;
@@ -0,0 +1,8 @@
import ReactOnRails from 'react-on-rails';

import HelloWorld from '../bundles/HelloWorld/components/HelloWorldServer';

// This is how react_on_rails can see the HelloWorld in the browser.
ReactOnRails.register({
HelloWorld,
});
104 changes: 104 additions & 0 deletions lib/generators/react_on_rails/templates/base/base/babel.config.js
@@ -0,0 +1,104 @@
// The source code including full typescript support is available at:
// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/babel.config.js

module.exports = function (api) {
const validEnv = ['development', 'test', 'production'];
const currentEnv = api.env();
// https://babeljs.io/docs/en/config-files#apienv
// api.env is almost the NODE_ENV
const isDevelopmentEnv = api.env('development');
const isProductionEnv = api.env('production');
const isTestEnv = api.env('test');

if (!validEnv.includes(currentEnv)) {
throw new Error(`${
'Please specify a valid `NODE_ENV` or ' +
'`BABEL_ENV` environment variables. Valid values are "development", ' +
'"test", and "production". Instead, received: '
}${JSON.stringify(currentEnv)}.`);
}

return {
presets: [
isTestEnv && [
'@babel/preset-env',
{
targets: {
node: 'current',
},
modules: 'commonjs',
},
'@babel/preset-react',
],
(isProductionEnv || isDevelopmentEnv) && [
'@babel/preset-env',
{
forceAllTransforms: true,
useBuiltIns: 'entry',
corejs: 3,
modules: false,
exclude: ['transform-typeof-symbol'],
},
],
[
'@babel/preset-react',
{
development: isDevelopmentEnv || isTestEnv,
useBuiltIns: true,
},
],
['@babel/preset-typescript', { allExtensions: true, isTSX: true }],
].filter(Boolean),
plugins: [
'babel-plugin-macros',
'@babel/plugin-syntax-dynamic-import',
isTestEnv && 'babel-plugin-dynamic-import-node',
'@babel/plugin-transform-destructuring',
[
'@babel/plugin-proposal-class-properties',
{
loose: true,
},
],
[
'@babel/plugin-proposal-object-rest-spread',
{
useBuiltIns: true,
},
],
[
'@babel/plugin-transform-runtime',
{
helpers: false,
regenerator: true,
corejs: false,
},
],
[
'@babel/plugin-transform-regenerator',
{
async: false,
},
],
[
'@babel/plugin-proposal-private-property-in-object',
{
loose: true,
},
],
[
'@babel/plugin-proposal-private-methods',
{
loose: true,
},
],
process.env.WEBPACK_SERVE && 'react-refresh/babel',
isProductionEnv && [
'babel-plugin-transform-react-remove-prop-types',
{
removeImport: true,
},
],
].filter(Boolean),
};
};
Expand Up @@ -41,5 +41,5 @@
# different. You should have ONE server bundle which can create all of your server rendered
# React components.
#
config.server_bundle_js_file = "hello-world-bundle.js"
config.server_bundle_js_file = "server-bundle.js"
end
@@ -0,0 +1,18 @@
// The source can be found at:
// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/clientWebpackConfig.js

const commonWebpackConfig = require('./commonWebpackConfig');

const configureClient = () => {
const clientConfig = commonWebpackConfig();

// server-bundle is special and should ONLY be built by the serverConfig
// In case this entry is not deleted, a very strange "window" not found
// error shows referring to window["webpackJsonp"]. That is because the
// client config is going to try to load chunks.
delete clientConfig.entry['server-bundle'];

return clientConfig;
};

module.exports = configureClient;
@@ -0,0 +1,17 @@
// The source can be found at:
// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/commonWebpackConfig.js

// Common configuration applying to client and server configuration

const { webpackConfig: baseClientWebpackConfig, merge } = require('@rails/webpacker');

const commonOptions = {
resolve: {
extensions: ['.css', '.ts', '.tsx'],
},
};

// Copy the object using merge b/c the baseClientWebpackConfig and commonOptions are mutable globals
const commonWebpackConfig = () => merge({}, baseClientWebpackConfig, commonOptions);

module.exports = commonWebpackConfig;
@@ -0,0 +1,28 @@
// The source code including full typescript support is available at:
// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/development.js

process.env.NODE_ENV = process.env.NODE_ENV || 'development';

const { devServer, inliningCss } = require('@rails/webpacker');

const webpackConfig = require('./webpackConfig');

const developmentEnvOnly = (clientWebpackConfig, _serverWebpackConfig) => {
// eslint-disable-next-line no-unused-vars
const isWebpackDevServer = process.env.WEBPACK_DEV_SERVER;

// plugins
if (inliningCss) {
// Note, when this is run, we're building the server and client bundles in separate processes.
// Thus, this plugin is not applied.

// eslint-disable-next-line global-require
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
clientWebpackConfig.plugins.push(new ReactRefreshWebpackPlugin({
overlay: {
sockPort: devServer.port,
},
}));
}
};
module.exports = webpackConfig(developmentEnvOnly);
@@ -0,0 +1,12 @@
// The source can be found at:
// https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh/blob/master/config/webpack/production.js

process.env.NODE_ENV = process.env.NODE_ENV || 'production';

const webpackConfig = require('./webpackConfig');

const productionEnvOnly = (_clientWebpackConfig, _serverWebpackConfig) => {
// place any code here that is for production only
};

module.exports = webpackConfig(productionEnvOnly);