JavaScript is typically used in two forms. There is the production and development version. The development version is used for development, troubleshooting, bug fixing, when you need to step through execution, etc. We should provide a toggle to allow switching between production/development JavaScript.

A simple implementation can be found in the speedy module.

This is a setup task to start shipping with minified JavaScript files in addition to the development version. The naming for production/development is taken because this is the naming convention used on jquery.com.

Crell, #18:

Note that we do now have a DrupalKernel class, extending Symfony's Kernel class, that has a dev/prod mechanism in it. We're just not using it at all yet, but it's there.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Crell’s picture

If we do this, it shouldn't be limited to just Javascript. It could easily apply to caching (page and block caching, or whatever that turns into in D8), theme caching, debug information etc.

The trick is figuring out how to do that without resulting in a global variable and 10,000 if statements throughout the system.

mfer’s picture

@crell - I think you are correct on this. Any suggestions?

Here is a possibility and I'm going to make 3 simple assumptions.

  1. This flag will be used by other systems and should be generalized. It's global and other systems will work out the implementation details. That means it can be a system wide variable.
  2. We need to describe a JS file as dev/prod/both. If statements are one way. A flag on drupal_add_js is another way. No matter which way we go we should default to both. You opt into describing it as being dev or prod. This is for the lazy develops to keep things working rather than exploding. I welcome challenges to this one.
  3. You might have some extra JS loaded just for development (think devel module) so it's not a one to one for every prod file there is a dev file and vice versa.
drupal_add_js('foo.min.js', array('site_mode' => JS_PRODUCTION));
drupal_add_js('foo.js', array('site_mode' => JS_DEVELOPMENT));

Thoughts? Refinements? Better ideas?

I do like the idea of passing this descriptive information a layer lower. If we make our JS handling pluggable it would be nice information for that system to know about.

BTMash’s picture

I'm coming into the issue via http://engineeredweb.com/blog/why-hard-minify-on-the-fly/ so I haven't thought about what such a toggle should be limited to though it makes sense (though as you also say, having a huge number of if statements is going to be quite pain.

As such, I haven't thought the larger idea through but for the js (and I suppose for the css as well?), I can imagine doing something similar to how the css file detection for right-to-left exists (ie suffix of -min.js or -min.css? look at http://api.drupal.org/api/drupal/modules!locale!locale.module/function/l...) which would look for the optimized versions of those files and adds those if we're running in 'production' mode.

EDIT: I didn't see the nice post by @mfer above which sounds really nice.

mfer’s picture

@BTMash The difference between JS files when we deal with external libraries and drupal only css is huge. Not all libraries use .min.js for their shipped minified files. Should we ask Drupal devs to rename external libraries to our naming schemes? With Drupal css we create them and it's easier to set a naming convention for a feature.

BTMash’s picture

I was referring specifically to drupal internal css/js. The flag that you have expands on the idea in that other modules are free to do work with the environment being dictated (so if a module is dealing with external js/css (or even internal) and it sees the production flag is up, it can add the necessary production version of the file(s) directly). And I was in agreement with your method - the way you have it (specify which type of js/css belongs in which environment) makes a lot of sense as well.

Wim Leers’s picture

I agree with @Crell, but I think it's useful to be able to "set everything except X in production mode", i.e. don't use a single setting. But of course @Crell may have already implied that. I just wanted to make it explicit.

Crell’s picture

I didn't say that, but I can see the argument for it. :-)

mfer: It seems that there is a *.min.js standard at least de facto for minified JS files. Can't we just say "if in prod mode, look for a .min.js file and use that instead if found"? That seems like it would catch the majority case with no effort on the part of module devs.

Asking module devs to think about when certain JS files are appropriate is a losing proposition. We can't even get them to figure out head vs. footer for JS.

Also, drupal_add_js() needs to go away entirely. But that's another story. :-)

nod_’s picture

Can you elaborate on drupal_add_js please? I'm interested now.

mfer’s picture

@crell How about this. We create a way for drupal_add_js (or it's replacement) to be told what to include when and we try to automate the process with .min.js files. So, we can make it smart and help developers who want to work around the smart.

@_nod drupal_add_js/css need to go away to something with a better api and setup. That discussion is for other issues and people who want to carry that torch.

Crell’s picture

So, something like:

array(
  'js' => 'foo.js',
  'min' => 'foo.minified-version.js',
);

Where the default for min if not specified is the value of the js key with ".min" inserted into it?

I could live with something like that.

sun’s picture

That would be similar to Libraries API's registration of variants per library.

While I can see that working for pre-registered/predefined libraries, I don't think this will work with the current way of how independent JS/CSS files are added to a page.

FWIW, I'm not confident that we'll reach a point where each and every JS/CSS file will be registered/predefined as a library. That is, because there's still quite a difference between a frontend library delivering unique functionality/behavior/styling and arbitrary/specific frontend files provided by modules and themes. Doing so would also make theming significantly more complex.

Crell’s picture

Most themes I've seen don't have conditions in their CSS/JS usage. They just specify code in their .info file. Could we do the sort of logic discussed in #9/#10 in the info file, much as we do for media types for CSS? Or would that make the file too complex? (Or is that an indication we should start looking at using CMI-style XML instead of info in order to support more such use cases?)

I'm mostly just brainstorming here. In general I agree with having a "dev mode", but there's a lot to work out.

RobLoach’s picture

I suppose it would be like this:

$libraries['keepitsimplestupid'] = array(
  'js' => array('foo.js'),
  'js-min' => array('foo.min.js'),
  'css' => array(
    'foo.css',
    'foo-kungfoo.css',
  ),
  'css-min' => array('foo.min.css'), // both foo.css and foo-kungfoo.css
);

We simply would not support this for individual files being added. We should move the majority of those over to hook_libraries_info so we can eventually AMD them up.

Most themes I've seen don't have conditions in their CSS/JS usage. They just specify code in their .info file. Could we do the sort of logic discussed in #9/#10 in the info file, much as we do for media types for CSS?

The problem with declaring it in the .info file is that there is no context applied to when the file is added. This means that it's added to every page, whether or not it's needed. It's much better to use #attached or drupal_add_library when needed. This is something we'll be doing at #1541860: Reduce dependency on jQuery (use jQuery only when needed).

klonos’s picture

...coming from #1389058: Update html5shiv-printshiv to the latest (minified) version - currently 3.7.2 and #1341792: [meta] Ship minified versions of external JavaScript libraries + other issues where it is debated which versions (minified vs non-minified) of libraries should be used.

I just want to point that there seems to be a common agreement that minifying on-the-fly is quite difficult at the moment for various reasons (postpone for D9 perhaps). One of the most important concerns with the current solutions is how to minify the actual code part of the files, but leave any license info comments intact. A fast and easy workaround is to include both minified and non-minified versions of the libs (so not to violate license) and come up with a way to switch between minified/full versions through the UI (à la the offline/online mode we currently have). The first part is only a matter of policy/decision and then doing the actual dual-file shipping with core. The second part will be handled in this issue here.

I guess what I'm trying to say is that implementing this feature request here has the pleasant side-effect of partially solving the license violation on minification issue I mentioned above as well. So +1 and I think that this should be mentioned in the issue's summary as an extra gain (besides the performance and dev/production gains I mean). If there's no objection, I'd like to add this info in the summary.

Wim Leers’s picture

#12: in that case, I think it would make a lot of sense to let d.o's packaging scripts generate a minified version automatically for projects that don't have it already. We don't want to ask every single maintainer to manually minify all of their CSS/JS.

That being said, I *don't* think we should ship minified files at all. I think we should solve the minification in core issue. And it looks like we're getting very close to solving the licensing roadblock: #119441-160: Compress JS aggregation.

RobLoach’s picture

#15: There are a few problems with on-the-fly compression:

  1. It's expensive on the server
  2. All the PHP libraries out there won't get us as far as what Grunt and UglifyJS will give us
  3. It's already done for us in most cases. Most libraries out there already ship compressed versions of their assets (which is in most cases done by UglifyJS)

Taking that into account, compression is not the way we want to go for Drupal Core. It might be best left to contrib (Speedy, agrcache, etc). On-the-fly aggregation is a good though, as it means less http-requests and still is fast on the server.

This leads me to this question... What the difference is between a Production/Development Toggle for CSS/JS and the Aggregate JavaScript files/Aggregate and compress CSS files toggle in admin/config/development/performance?

Grayside’s picture

Is this issue specific to JS, or does it encompass end-to-end? Environment and Mode being just a couple modules at my fingertips that use this concept to automate code & configuration change for deployment and testing.

Crell’s picture

Note that we do now have a DrupalKernel class, extending Symfony's Kernel class, that has a dev/prod mechanism in it. We're just not using it at all yet, but it's there.

I think there's a good use case for a system-wide dev/prod flag, provided we still have the option of doing more fine-grained control.

klonos’s picture

@Crell: Hey Larry, I've included your comment in the issue summary so it doesn't get lost if this issue becomes too big. Hope you don't mind.

mfer’s picture

@Grayside I took a look at the the Environment and Mode module. They appear to to solve a slightly different problem than what I'm proposing here. If I'm not right on this please correct me.

The environment module lets you specify differences in Drupal config per environment. This could be a production environment and a development environment. But, what if you have the case where you want to log some extra bits in development but not in production? It appears to be about switching from one environment to another automatically. For example, to disable the develop module.

The Mode module appears to operate around permissions which is a different space.

So, while I agree these modules can be useful I think they are solving a different problem.

Fabianx’s picture

A general switch to turn on / off debugging would be really helpful also for Twig. ( not only restricted to JS)

hefox’s picture

> The environment module lets you specify differences in Drupal config per environment. This could be a production environment and a development environment. But, what if you have the case where you want to log some extra bits in development but not in production? It appears to be about switching from one environment to another automatically. For example, to disable the develop module.

Environment defines a way to check what environment the site is

if (environment == development ) {
   watchdog(..)
}

Our use of environment modules involves having a three state -- production, development, readonly. However, the readonly is problematic as being part of those 3 -- read only mode should really be useable during production (e.g. there should be two separate sets: production, development; read, read only).

However, there is a case for a multiple state, I think: production, staging, development (, testing), so it'd be nice if core out of box supported this (even if it only came with 2 main states to begin with). Not sure if whatever system core has would find it useful to define

How I'd imagine it working, based on how used environment module:
Core would default to development mode to begin with, variables default to
Overriding configuration have a way to specific what mode/s they should apply to
Modules/etc. can react to a change in mode (if they need to enable/disable modules -- e.g. enable devel during development)
Modules/etc. can define new states

Robin Millette’s picture

I'd also like to see this used in the usage statistics. 5000 sites use my module, great, but how many of those are dev sites? How many are actually in production? I'd like to know.

Crell’s picture

I don't know that is relevant, actually. The goal here is to have explicitly separate "I'm working on things" and "I care about performance" modes. There's lots of things we could build off of that. The number of people that are using workarounds now to get part way to that doesn't change that there's a lot more we could do if we had something like that baked in.

Just as services module is only used by a small number of sites, and deploy by even fewer, but we're rewriting our whole routing system to support web services anyway because it's the right thing to do, architecturally. :-)

decafdennis’s picture

Component: javascript » base system
Fabianx’s picture

Issue tags: +Twig

Adding Twig tag. I really *need* this.

hefox’s picture

The dev/production environment switch in Kernel doesn't seem to be documented much to what it does exactly (Didn't look too much though). It's a string, so not sure if it's restricted to production/development (prod/dev?)

It's set via the construction, for example index.php has

$kernel = new DrupalKernel('prod', FALSE, NULL, cache('bootstrap'));

and gotten via getEnvironment() function. It's current use is for determining the container class/building the container class.

It seems like having a separate issue for minification might be best where it's added via a configurable toggle like css/js/etc. aggregation, and not intertwine it with the issue of adding production/development toggle (other than the default, like with aggregation, is somehow based on environment).

Interesting thought is that production could remove the UI for changing variables like aggregation/minification.

Crell’s picture

The way Symfony fullstack uses it is to offer 3 environments: dev, prod, and test. test is only used during integration testing. The others are handled via different front controllers. Vis, there's app.php which has prod hard coded, and app_dev.php that has dev hard-coded but is otherwise identical. Since Symfony's request handling is more robust than Drupal 7's was (and we're now using Symfony's in Drupal 8), that works fine and you can go into "Dev mode" by just tweaking your URL. That results in slightly different config files getting loaded, different containers, etc.

I don't know that we can or want to handle different environments via alternate front controller files, but allowing arbitrary environments (with direct support only for dev and prod) that have slightly different config (mostly for things like "should we recompile Twig files on every page request" or "should we aggregate CSS files") makes total sense.

Fabianx’s picture

#28: I agree, I envision this currently like:

Current Environment: [Dev]

Select Environment --> Dev, Test, Prod

[ ] Aggregate CSS
[X] Recompile Twig files on each request

[ Save ] [ Switch Environment ]

Or similar ...

Then you can switch configs for environments via AJAX or whatever and switch between environments easily.

It is a little like presets and quite powerful ...

Crell’s picture

The problem with a UI toggle is where to save it. It has to be to a system that is readable pre-kernel. Right now, we don't have one of those. All we have is directly reading a YAML file or the PHP Storage system; The former is too slow, the latter is not guaranteed to exist. Everything else is only usable post-kernel (CMI, State, etc.).

A manual $conf variable in settings.php or separate front controllers seem like the only practical options.

Fabianx’s picture

I am happy with a $conf variable in settings.php to switch between different configs for certain admin screens.

Installer could ask if you want to enable development mode and write settings.php accordingly?

Grayside’s picture

Speaking from experience, UI for environment toggling is buggy. If lots of operations are tied to it, it needs special memory handling. And yes, can have odd race conditions with different subsystems. drush integration can be nice though.

I'd like to second #27:

It seems like having a separate issue for minification might be best where it's added via a configurable toggle like css/js/etc. aggregation, and not intertwine it with the issue of adding production/development toggle (other than the default, like with aggregation, is somehow based on environment).

Items leaning on this environment toggle should have their own state, environment should be a meta-state. That way if developers need to take surgical actions, like test one "dev" component of the system in an otherwise production environment, it is possible.

hefox’s picture

Looking into writing to settings.php

Fully possible to write it during install.php. However, only form/steps that seems relavent to add to is the database configuration one, but that seems a bit misplaced. The last site configuration one seems a bit too late and it's after the "change settings.php permission back" message (that can be moved, but there's some comments above the message suggesting how it'd be bad if it was there).

Is there a system already in place for changing configuration like this? I believe there is, as domain and spaces type modules needed something like that (though this is different -- domain & spaces just need temporary overrides, this needs more permanent defaults), but don't know the details. If someone can point me in right direction, I'd like to try and implement it.

My guess is any IU outside of perhaps a settings.php toggle (or maybe just not have that and just have a settings.php variable) could be handled by contrib -- considering the timing, etc.

Another thing to note: currently things like css/js aggregation is turned off by default, but the current enviroment as set in index.php is production (which would likely have css/js aggregation on).

Crell’s picture

The problem with a settings.php variable is that it is then impossible to change mode without code/shell access, to a file that many people check into Git. A listener can't do it, because it happens after the container is active, but the container is one of the things we want to switch out.

quicksketch’s picture

For APC integration, why wouldn't you just detect if APC was available, then automatically use it? There's no need for a toggle at all. A checkbox for "would you like a slow site or a fast site?" is silly with regards to APC. It has absolutely no other affect on your site (unlike JS/CSS aggregation) other than making things go faster. If you're a developer and turn on xdebug, APC is automatically disabled. Or if you're running XHProf, combining with APC is totally allowed. Or systems like MAMP or WAMP allow toggling of APC in their UIs. There's no real question about it. If the server has APC, you use it. If you don't want Drupal to use APC, you turn off APC.

Crell’s picture

quicksketch: Restarting apache to clear your cache is bad DX. During development, I want nothing cached. NOTHING.

Developing with APC on is not bad. It's actually faster than not doing so. Don't force me to turn it off because Drupal can't not-cache something. (We're broken enough as is on that front.)

dww’s picture

I haven't followed all of this closely or pondered all the implications, and I'm *way* out of the loop on D8 development. However, when I was re-writing the update manager to be included in D7 core, all that authorize.php plumbing that it uses to install new modules as the user that owns the files, not the user that the webserver is running as, was designed with the idea that it could be reused for stuff like the installer and/or something like this. In theory, we *could* write this toggle directly to settings.php, even without shell/code access, even from the UI. Not sure that's a good idea, but it's something to consider.

quicksketch’s picture

Developing with APC on is not bad. It's actually faster than not doing so. Don't force me to turn it off because Drupal can't not-cache something. (We're broken enough as is on that front.)

I mentioned this over in #1971198: [policy] Drupal and PSR-0/PSR-4 Class Loading, but if you wanted to turn off APC caching, that would be a logical setting for settings.php. Turn APC caching on by default if it's available, and allow it to manually be turned off in settings.php.

quicksketch: Restarting apache to clear your cache is bad DX. During development, I want nothing cached. NOTHING.

Well in that case you wouldn't be running with APC on in the first place. Not all developers share this sentiment. There are many, many "developers" that only build sites through the UI: Views, Panels, Rules, etc. For them, any additional time caused by not having caching on code they're not touching is a waste.

Crell’s picture

I was referring specifically to developers as "people who write codez", not to site builders. I thought that was rather obvious from context.

Sylvain Lecoy’s picture

I am generally against a toggle. Which imply tests hock in the code. E.g. if (prod).

This should be avoided, instead using multisites capabilities such as a staging, dev and prod. They may share common modules but different configuration. Hence no need for a test hock.

RobLoach’s picture

Although I enjoy the idea of having One Toggle To Rule Them All, it is much easier to debug issues by having the control to enable/disable the individual toggles selectively. Maybe if we kept what is there currently, but had the Development/Production toggle just wizardize the Performance page using States...

  • [ ] Development
  • [x] Production
  • [ ] Custom
Pancho’s picture

Without being aware of this proposal here, I came up with a very similar idea in #1925822-13: Stop locking me out of my own sites/default directory if Drupal is already insecure, some of the aspects might be interesting for this.

Sylvain Lecoy’s picture

#41, what if you need more than Development, Production, and Custom ?

Such as Staging, Integration, Quality ?

Will you need tests hock in code (such as if (dev) {} blocks) with this solution ?

Why do people does not believe in the sites/ approach where you can have arbitrary any environments you need:

sites/all
sites/production
sites/integration
sites/qualification
sites/staging
sites/local

Where in sites all you have all the common modules to your application, and in each subsites, the configuration (through settings.php, features, code, ...) and modules which overrides default one for this specific site.

For instance, in the production folder, I would have an apc module, which is not in the local folder. I would have devel, coder module in the local folder but not in the staging folder. Additionally, I would put a secure module in qualification, integration and production, with different parameters dispatched respectively in settings.php files and/or features specific to these environments.

This would also mean, that the DI Container would be compiled and dumped on a site folder basis, hence they will be different between environments. To eventually optimize the solution, we could remove the logic which appear early in the bootstrap process (DrupalKernel) which is responsible for loading a class container based on $debug and $prod parameter and rely on the php file generated on a per site basis.

Sylvain Lecoy’s picture

Issue summary: View changes

...adding Crell's comment in #18 about DrupalKernel and the dev/prod mechanism in Symfony's Kernel class

sun’s picture

Issue summary: View changes

Note that #2226761: Change all default settings and config to fast/safe production values contains a concrete proposal for a first baby step.

Wim Leers’s picture

#2226761: Change all default settings and config to fast/safe production values landed. It introduces CSS/JS aggregation enabled out of the box.

AFAICT aggregated & minified JS was the primary reason for opening this issue. The aggregated part is now already addressed. The minified part has one blocker: the licensing aspect. I worked on that over the past weekend, resulting in #2258313: Add license information to aggregated assets. If we can get that one in also, then we could add JS minification at a later time to Drupal 8!

cweagans’s picture

Status: Active » Needs review
FileSize
4.6 KB

I think we can ignore the UI for now. The feature is useful even if it's only ever used by developers. Having a standard dev/prod variable that contrib modules and various places in core can use seems very useful to me. We've also already established the pattern of changing different configuration flags in settings.local.php, so let's just do the same with the development toggle.

One related thing that I'd like to do once this is in is start using https://github.com/filp/whoops when Exceptions are thrown in development mode. This has been very useful to me when I'm working with Laravel, and I'd love to bring it to Drupal.

Status: Needs review » Needs work

The last submitted patch, 46: 1537198_45.patch, failed testing.

cordoval’s picture

This is what i understand from conversations with @cweagean:

The DrupalKernel gets the environment already injected into the constructor

The Settings wraps the settings.php parameters controlled by the user

On handle request or those tasks DrupalKernel gets initialized with $environment, it is here where we can do

<?php

$environment = fn(Settings::get('debug_mode_or_whatnot'));
... new DrupalKernel($environment, ...);
?>

Everything downstream should depend on the environment in the services etc.

There are some things that need to be thought probably starting from giving the user some flexibility on the parameters passed and how they resolve or get overridden or override the environment.

Wim Leers’s picture

#46: I'm not sure I follow. This will result in rehashing of many things discussed in #2226761: Change all default settings and config to fast/safe production values.

The problem is that in *my* development mode, I don't want Twig debug, twig autoreloading to be enabled, but only CSS and JS aggregation to be disabled. Somebody else will want the opposite. And so on.

That's why we settled on the simple settings.local.php approach of #2226761: Change all default settings and config to fast/safe production values: so that anybody could craft his/her "own" development mode. Everything that you're doing here doesn't belong in Drupal core, precisely because it will never be good for everybody. It's trivial for any Drupal shop or freelancer to develop his own system just like the patch in #46: a "development mode", a "theming mode", a "demo mode", any mode that's relevant for that shop/project/person's needs.

(What you've done here doesn't need all those changes to files other than example.settings.local.php; instead, you can conditionally apply settings overrides based on the value of the development_mode setting you added. This is why I say that anybody can create his/her own modes! :))

What you're proposing is precisely the first proposal I posted in #2226761, which was shot down — for good reasons. Let's not reiterate that discussion :)

This issue should either be closed or retitled to just cover the minified/unminified JS assets problem (see #45).

sun’s picture

@Wim Leers: That discussion was certainly not complete. #2226761: Change all default settings and config to fast/safe production values simply chose the most straightforward path forward for the sake of avoiding scope creep, no more, no less.

The resulting changes to settings.local.php of that issue did cause a fair amount of confusion for developers already; they definitely need to be re-thought. But that's slightly off-topic here.

We should revisit and complete that discussion. That said, I'm not sure whether this is the right issue to do so - a dedicated issue might be more fruitful/appropriate.


I like the train of thought of @cordoval in #48 — closely resembles what @neclimdul and I already discussed for #2016629: Refactor bootstrap to better utilize the kernel; bottom line:

Settings presents a dependency to DrupalKernel, it should be injected into the kernel.

thedavidmeister’s picture

This has now become related #2081873: Re-implement module disabling in a temporary/debugging capacity that is environment aware and explicit about risks to data integrity, in that we want some way to detect environments over there.

This issue really needs an issue summary update to stop talking only about JavaScript.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dawehner’s picture

#2766509: Gracefully handle a non-existent cache service like cache.backend.memcache is another example where a prod/dev toggle , not multiple environments, would be the better solution. In this case on prod we want to avoid fatals, at all costs. On dev though we want to tell people as fast as possible that something might be configured wrong, and maybe fatal/throw a helpful exception.

Wim Leers’s picture

dawehner’s picture

Status: Needs work » Needs review
FileSize
2.55 KB

Here is a fresh start. Explicitly this is not about stuff like caching, its all about errors and reporting errors.
I'm curious what people think about this alternative approach/idea/concept.

larowlan’s picture

+++ b/core/lib/Drupal/Core/Database/Query/Condition.php
@@ -243,6 +244,9 @@ public function compile(Connection $connection, PlaceholderInterface $queryPlace
+            if (Settings::get('development_mode', FALSE)) {
+              throw new \InvalidArgumentException('Invalid characters in query operator: ' . $condition['operator']);
+            }

The line above says we cannot throw exceptions here, can you elaborate on the intention of this change? Perhaps updating the comment?

dawehner’s picture

The line above says we cannot throw exceptions here, can you elaborate on the intention of this change? Perhaps updating the comment?

I added an additional sentence that we throw the exception still in dev mode, does that help?

@larowlan
It would be great to get a general :+1: from a framework maintainer about the idea to have a toggle for things which should be different in prod and dev (mostly exceptions I think).

larowlan’s picture

I think we should keep it simple, this patch certainly does that.

Personally I have a settings.dev.php that I gitignore.

I know I'm in development mode. Core and contrib does not.

I think that is where we might get into trouble. We don't want core/contrib making assumptions about how to handle things based on this flag, we want to be able to set it to what suits us.

However, I get that exception handling is a different case. However we already have error_displayable() for that. If that's not enough then perhaps we could add a different option for exceptions. i.e. instead of a blanket 'development mode' flag, more granular flags. And documentation in an example.settings.php - perhaps splitting out default.settings.php into default.settings.php and default.settings.local.php with a big section on available development friendly options that can be toggled.

So, I'm not convinced - yet. @WimLeers' comments in #49 are consistent with what I'm saying above.

The issue summary talks about minified vs non-minified JavaScript. But we're talking about exceptions and error handling - so we definitely need an issue summary update. If we're still talking about minified vs non-minified JavaScript, then that feels like a case for a different settings alongside $conf['preprocess_js'] for serving non-minified versions of Javascript libraries?

So tl;dr I don't have enough information yet.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

SKAUGHT’s picture

Issue tags: +Drupal 9

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

bradjones1’s picture

Status: Needs review » Needs work
Issue tags: -JavaScript +JavaScript

I'm going to be bold and mark this NW as there's a lot to hash out.

Also the latest patch uses Drupal's bespoke settings construct; i think there should be more discussion around whether we want more in the settings singleton as opposed to preferring something more like the environment flag in the kernel (see #18.)

This does raise a broader question about the "proper" way to hint dev/prod toggles in Drupal, or any software distribution for that matter. The Twelve-Factor App advises against having lots of configuration toggle on a single flag like this:

In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as “environments”, but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime.

I think that's largely correct, although in practice seems like a laudable goal/guiding principle rather than a hard line.

This does speak to the concern in #61:

We don't want core/contrib making assumptions about how to handle things based on this flag, we want to be able to set it to what suits us.

Honestly, I think this ship has sailed; custom code often implements something akin to getenv('ENVIRONMENT') and APP_ENV is standardized in Symfony.

That brings me to: the bigger motivator here for doing this is because it allows us to base more runtime behavior on the Kernel's configuration. There are many issues open for making Drupal less bespoke and swim with Symfony than against it. See #3228629: [meta] Bring dependency injection more in line with upstream Symfony component.

E.g. with regards error display:

However, I get that exception handling is a different case. However we already have error_displayable() for that.

This is a good example of Drupal providing its own implementation of what is basically symfony/error-handler and the symfony kernel's debug setting do, but we largely reinvent.

We could even go further and push more of this to the application bootstrap level and make Drupal far more agnostic about how and where it is run. For instance, we could implement symfony/runtime and have the runtime environment decide what "environment" we are in and further, if we are debugging. This helps decouple the environment indicator from things like saying, should we debug (e.g., not minify CSS/JS) or whatever.

tl;dr: I think we are bikeshedding here a bit and this is an opportunity to let Symfony paint it for us and focus on things Drupal does in its own distinct domain.

bradjones1’s picture

bradjones1’s picture

An addendum to my comment above - I think this is as much about supporting APP_DEBUG as APP_ENV. See the docs on the runtime component (which I'm liking more and more for Drupal if we could get away with such a "big" change.)

Edit: Added #3313404: Use symfony/runtime for less bespoke bootstrap/compatibility with varied runtime environments for symfony/runtime implementation as I'm digging this more and more to solve a number of related but different issues like this one.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

voleger’s picture

Version: 9.5.x-dev » 11.x-dev