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

Provide a watching build mode that writes to the disk in development #1070

Open
andreypopp opened this issue Nov 20, 2016 · 64 comments

Comments

Projects
None yet
@andreypopp
Copy link
Contributor

commented Nov 20, 2016

See #1018 (comment) for a discussion which leads to the creation of this issue.

I propose adding a new command (working name build-dev) which watches for changes and rebuild the bundle (effectively, given the current CRA implementation, it should execute webpack --watch), then writes it onto filesystem.

The main motivation is an easier integration path with non-Node.js dev servers: such servers could just serve continuously updating bundle from the filesystem.

The only desired configuration options is an --output, which could probably be specified via a command line argument:

% npm run build-dev -- --output ../static/www

Alternative command name suggestions:

  • watch
  • build-watch
@gaearon

This comment has been minimized.

Copy link
Member

commented Nov 20, 2016

My concern: the concept of a dev server is already confusing to many people and I've seen countless issues from people trying to find dev server output in the filesystem, adding scripts with hrefs to local files, when they didn't need it.

So I'm worried introducing this feature is useful in some advanced cases but might make everything more confusing in simple cases for people who mistakingly start with build-dev instead because they haven't seen a dev server before when dev server is exactly what they need.

@leftdevel

This comment has been minimized.

Copy link

commented Nov 21, 2016

(As the OP of #1018) :
For me it all boils down to:

  • Write the dev bundle that results from running npm start, to the file system.
  • 'watch' for changes (in dev mode).

@gaearon makes a great point saying that CRA biggest win is saving the developer from configuring the dev server which is the most difficult feature. I'd be happy if at least we could access the dev bundle.js file from the filesystem, I wouldn't care if the dev server is started, I would just ignore it.

My argument is that:

CRA is quite appealing to non Node.js developers. There are many experienced developers in python, php, .net out there, but not all of us/them are that experienced in frontend set ups.

CRA makes it a no-brainer to use react. And to be honest, these days it's way more difficult to set up a React project than an ember or angularjs 1.x project. React API is pretty simple and powerful, but when you introduce React to your organization projects, it's not just React, but all its friends which are hard to master (webpack, babel, presets, linters, etc).

Not sure if you guys have read this blog post yet https://goo.gl/HviDRn, but it's about a company that has a backend in Flask and were evaluating a frontend framework. They talk about how difficult is to keep up with the shifting ecosystem around React, and I'd totally agree on their pain points. At the end they chose Emberjs because of their CLI tools that makes it super easy to integrate.

I think CRA was created with the mindset of helping people that are just starting with React, and playing around with a few simple tutorials, but it has the potential of becoming a profesional tool for people that don't have that much time to spend learning webpack, babel, if to use fetch or superagent, what Promise polyfill to use, etc.

We need something opinionated that just works. Note that I'm totally fine with the already existing features in CRA.

Sorry for the long post.
** flies away **

@gaearon

This comment has been minimized.

Copy link
Member

commented Dec 6, 2016

Tagging with a milestone so I remember to get back to it.

@viankakrisna

This comment has been minimized.

Copy link
Contributor

commented Jan 12, 2017

I think this is the same as #1316 should i just close that?

@gaearon

This comment has been minimized.

Copy link
Member

commented Jan 12, 2017

Yea, this is the same.

@gaearon gaearon changed the title Provide a new command which watches for changes and rebuilds bundle Provide a watching build mode that writes to the disk Jan 12, 2017

@gaearon gaearon changed the title Provide a watching build mode that writes to the disk Provide a watching build mode that writes to the disk in development Jan 12, 2017

@viankakrisna

This comment has been minimized.

Copy link
Contributor

commented Feb 22, 2017

So I'm worried introducing this feature is useful in some advanced cases but might make everything more confusing in simple cases for people who mistakingly start with build-dev instead because they haven't seen a dev server before when dev server is exactly what they need.

Isn't this can be solved with proper documentation and gentle reminder when they use this feature? Would be happy to working on a react-scripts watch PR. I have 'ejected' several project because i need this feature.

@gaearon

This comment has been minimized.

Copy link
Member

commented Feb 22, 2017

I'm not opposed to adding it. Happy to take a look at a PR.

@aeneasr

This comment has been minimized.

Copy link

commented Apr 17, 2017

I'm currently using cross-env NODE_ENV=development webpack . --config node_modules/react-scripts/config/webpack.config.dev.js -w to achieve that. However, it requires adding webpack-cli to the node_modules.

The only problem is that appending the hash to the bundle's name bundle.[hash].js makes the entrypoint unpredictable which is why I'm still ejecting the scripts. Any way to resolve that?

@dkaplan-pivotal

This comment has been minimized.

Copy link

commented Apr 21, 2017

I want to add an additional story to add context to why I'd like this feature: We built our app with server side rendering and waited until we had a feature that would require enough js/ajax to justify a single page app. We got to that point and wanted to replace that one page with a react frontend. The plan would be that react would gradually expand to the rest of the app (if needed, maybe it'd never be needed).

But CRA appears to assume that in development mode, your frontend is a different app from your backend. That's not necessarily true if you want to bring react to an application that already exists. (Even if you go with the dual-app idea, you have to deal with CORS. I think you could argue that CORS complexity outweighs the output file complexity.)

So our workaround is to always build to production and copy the files into our server so they can be rendered. But the minification and source map generation adds an extra 10-15 seconds when we do that every time and we can't use a watch. When you want frequent, fast feedback loops, those 10-15 seconds add up to considerable lost time.

Let me know if I'm doing something wrong here. Maybe there's an obvious workaround here.

@viankakrisna

This comment has been minimized.

Copy link
Contributor

commented Apr 21, 2017

@dkaplan-pivotal I have the exact use case! There is a proof of concept here #1616 but i think #1994 & #1588 is a better solution (minimized risk of deploying development script + reload on file change). Good to see that #1994 & #1588 is tagged for 0.9.6.

@dkaplan-pivotal

This comment has been minimized.

Copy link

commented Apr 21, 2017

Thanks for your reply. @viankakrisna I don't see how #1994 & #1588 add up to a development mode where you can have a single page of your app use react.

@viankakrisna

This comment has been minimized.

Copy link
Contributor

commented Apr 21, 2017

#1994 and #1588 will allow you to include the development bundle to any of your local sites with live reloading. I've tested it by referencing the bundle on my local wordpress site and it reloads on file change. (haven't tested css hot reload because i'm using styled-components)

@ltoshea

This comment has been minimized.

Copy link

commented Apr 25, 2017

I'd just like to echo all the above, when loading resources from an external file it's a huge pain for the names to change every time you make a small change and rebuild.

@mythz

This comment has been minimized.

Copy link

commented Jul 29, 2018

+1 for this to be an officially supported feature. IMO watched builds provides the optimal development for non node.js server apps, proxying with the dev server is too laggy with the more ajax requests an app has the less enjoyable it becomes where often ajax responses get handled out of order.

@Nargonath

This comment has been minimized.

Copy link

commented Jul 29, 2018

@hopewise Did you manage to get the page reload as you wanted? Wondering if I should get a look at it.

@graysonhicks

This comment has been minimized.

Copy link

commented Oct 6, 2018

Trying to accomplish this for integrating with templates served with Drupal. Any update with this with v2?

@radi-ratlh

This comment has been minimized.

Copy link

commented Oct 17, 2018

This will be really useful when developing chrome extensions, instead of using prod bundle and getting incomplete error messages we can use the development bundle and debug the issue.

@Nargonath

This comment has been minimized.

Copy link

commented Oct 17, 2018

@radi-ratlh in the meantime perhaps the npm package I wrote could be of any help.

@radi-ratlh

This comment has been minimized.

Copy link

commented Oct 17, 2018

@Nargonath Thank you, I will give it a try

@andreisoare

This comment has been minimized.

Copy link

commented Nov 4, 2018

If create-react-app supports "Changing the title tag", "Generating Dynamic Tags on the Server", or "Injecting Data from the Server into the Page" for production, it should provide a way to support these features for development.

If it's part of your core for prod, it should be for dev as well and not defer to 3rd party plugins. Without the feature requested here I don't see an easy way to accomplish this.

Is this still not planned for the near future?

@dharmendra-sehgal

This comment has been minimized.

Copy link

commented Nov 21, 2018

image
For example, Half of that page is just normal django template code. And half of it is react code

I want to make stuff like this one-liner
'testpage' is a directory containing a react project

image

Did you find any solutions?

@devxpy

This comment has been minimized.

Copy link

commented Nov 21, 2018

@dharmendra-sehgal check out my project react-pages.

Feature requests and bug reports welcome!

@Friss

This comment has been minimized.

Copy link
Contributor

commented Dec 20, 2018

webpack-dev-middleware has an option writeToDisk and it can be enabled via webpack-dev-server (>=3.1.10 required)

With my PR above to get us to the required version of webpack-dev-server we could then add in some environment var(s) to enable the saving of files to disk. This could be 2 vars, 1 to enable and another to decide what directory to use. By default it uses dist. Or just one var to declare where to save the files and that enables the option to be set.

@Nargonath

This comment has been minimized.

Copy link

commented Dec 20, 2018

@Friss Wow that'd be really neat! Hope it goes through. 👍

@ioloie

This comment has been minimized.

Copy link

commented Jan 7, 2019

Now that this has been released, are further changes required to support the option?

@Nargonath

This comment has been minimized.

Copy link

commented Jan 7, 2019

@ioloie AFAIU from @Friss the feature needs to be implemented. His PR only updated the package version but we need the behavior to be enabled in webpack-dev-middleware through the use of environment variables as he suggested.

@suxin1

This comment has been minimized.

Copy link

commented Jan 9, 2019

What is the new way to do this?

@ioloie

This comment has been minimized.

Copy link

commented Jan 9, 2019

This pull request provides another environment variable called WRITE_TO_DISK. So adding WRITE_TO_DISK=true in the relevant place will enable the feature in the underlying webpack dev server

@Simonig

This comment has been minimized.

Copy link

commented Jan 22, 2019

An easy solution I find, is to use the already provided 'configFactory' (from config/webpack.config.js) to generate a development configuration for webpack:

//scripts/devConfig.js
process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';
const configFactory = require('../config/webpack.config');

// Generate configuration
module.exports = () => configFactory('development');

and then in the package.json create a watcher script:

  "scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "devWatcher": "webpack --config scripts/devConfig.js --watch",
    "test": "node scripts/test.js"
  },

you might also want to define a output folder in the webpack.config file, because I think that currently is only defined for prod

    output: {
      // The build folder.
      path: isEnvProduction ? paths.appBuild : undefined,

obviously I'm refering to a ejected project.

@Nargonath

This comment has been minimized.

Copy link

commented Jan 22, 2019

I also put on NPM a lib that helps you do it without ejecting: https://github.com/Nargonath/cra-build-watch while we wait for this PR to get merged.

@dariusrosendahl

This comment has been minimized.

Copy link

commented Feb 5, 2019

An easy solution I find, is to use the already provided 'configFactory' (from config/webpack.config.js) to generate a development configuration for webpack:

//scripts/devConfig.js
process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';
const configFactory = require('../config/webpack.config');

// Generate configuration
module.exports = () => configFactory('development');

and then in the package.json create a watcher script:

  "scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "devWatcher": "webpack --config scripts/devConfig.js --watch",
    "test": "node scripts/test.js"
  },

you might also want to define a output folder in the webpack.config file, because I think that currently is only defined for prod

    output: {
      // The build folder.
      path: isEnvProduction ? paths.appBuild : undefined,

obviously I'm refering to a ejected project.

@Simonig:

This works great! We're only using it to create react applications to integrate it into and e-commerce platform. What do I need to change to only watch multiple applications?

@ifokeev

This comment has been minimized.

Copy link

commented Mar 14, 2019

my similar to @dariusrosendahl solution:

you need install rewire first:

yarn add rewire

scripts/start-writeon-disk.js

#!/usr/bin/env node

const rewire = require('rewire')
const defaults = rewire('react-scripts/scripts/start.js')

const createDevServerConfig = defaults.__get__('createDevServerConfig')
defaults.__set__('createDevServerConfig', (...args) => ({
  ...createDevServerConfig(...args),
  writeToDisk: true,
}))

package.json

  "scripts": {
    "start": "./scripts/start-writeon-disk.js",
    ...
  }

NOTE: it doesn't drop CSS files this way

@route2Dev

This comment has been minimized.

Copy link

commented Mar 23, 2019

I found this to be a helpful implementation:
https://gist.github.com/int128/e0cdec598c5b3db728ff35758abdbafd

If this could cleanup the temp files gererated and be incorporated into CRA, that would be awesome!

@cowwoc

This comment has been minimized.

Copy link

commented May 1, 2019

I'm interested in this PR minus the watch bits. I don't want my CI smoke tests to run optimized bits because it is extremely slow. My less-frequent integration tests might run it, but the main CI pipeline should not.

Should I open a separate PR for this or will this PR target this use-case as well?

@cherukumilli

This comment has been minimized.

Copy link

commented Jun 14, 2019

webpack-dev-middleware has an option writeToDisk and it can be enabled via webpack-dev-server (>=3.1.10 required)

With my PR above to get us to the required version of webpack-dev-server we could then add in some environment var(s) to enable the saving of files to disk. This could be 2 vars, 1 to enable and another to decide what directory to use. By default it uses dist. Or just one var to declare where to save the files and that enables the option to be set.

writeToDisk is no longer working with create-react-app v3. I don't see it create the /dist folder. It used to work with create-react-app v2.
Trying to see if anyone else encountered this issue with cra v3? and if they have a solution to it?

@Nargonath

This comment has been minimized.

Copy link

commented Jun 14, 2019

How did you set it as this PR was never merged? Are you doing it with an ejected project?

@cherukumilli

This comment has been minimized.

Copy link

commented Jun 14, 2019

@Nargonath -
I forked this project and updated the react-scripts/config/webpackDevServer.config.js file.

    quiet: true,
    // WebpackDevServer has an option to write every build to disk. This can be
    // useful for certain use cases such as developing browser extensions where one
    // would need to otherwise do full builds.
    writeToDisk: true,

The above setting with a few other changes like

  "homepage": ".",

got my local dev environment working in CRA2.x

After merging in CRA 3.x, this stopped working. I don't see the /dist folder anymore.

wondering if anyone else is facing this issue?

@Nargonath

This comment has been minimized.

Copy link

commented Jun 15, 2019

Oh alright, didn't think of that option. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.