Open harel opened 8 years ago
+1, I'm facing the same issue
Hi, thanks for filing this issue.
I could not reproduce it. I have cloned git@github.com:jquery/globalize.git
, chdir to examples/app-npm-webpack
, ran npm install
, then npm run build
, which worked just fine.
Please, could you describe the steps you are taking in more details? Also, note that in the webpack config, we have the following code below, which is slightly different than the one you posted, which might suggest it's good to double check you have up-to-date example.
new GlobalizePlugin({
production: options.production,
developmentLocale: "en",
supportedLocales: [ "ar", "de", "en", "es", "pt", "ru", "zh" ],
messages: "messages/[locale].json",
output: "i18n/[locale].[hash].js"
})
Hi @rxaviers
I just omitted the optional messages key for now, but otherwise my config is the same - just with different locales. The error I'm getting is only when i run npm run build
and the production flag is set to true
.
I pasted my dependencies from packages.json. If it makes any difference, my build kinda stalls at around 50% for a good few seconds then continues until this error comes up. I also tried to do a build with just 'en' locale but no luck. This error is persistent. I've pretty much tried any configuration I can think of including different release candidates.
"dependencies": {
"globalize-webpack-plugin": "^0.2.0",
"bluebird": "^2.9.34",
"classnames": "^2.2.1",
"cldr": "^3.2.0",
"cldr-data": "^28.0.3",
"globalize": "^1.1.0-rc.7",
"history": "^1.13.0",
"immutable": "^3.7.6",
"jquery": "^2.1.4",
"json-loader": "^0.5.4",
"lodash": "^3.10.1",
"react": "^0.14.3",
"react-addons-clone-with-props": "^0.14.3",
"react-addons-pure-render-mixin": "^0.14.2",
"react-big-calendar": "^0.9.5",
"react-dom": "^0.14.2",
"react-intl-tel-input": "^2.0.2",
"react-redux": "^4.0.0",
"react-remarkable": "^1.1.1",
"react-router": "^1.0.0-rc3",
"react-widgets": "^3.1.3",
"redux": "^3.0.4",
"redux-logger": "^2.0.4",
"redux-thunk": "^1.0.0",
"semantic-ui": "^2.1.6",
"superagent": "^1.3.0",
"superagent-bluebird-promise": "^2.0.2"
},
Just in case, I tried with the messages key included. Still same result. @adros , I thought I was the only one, so bummer you're getting that error but I'm glad I'm not alone. Before I thought it might merit a ticket here I tried StackOverflow, but for some reason my question offended someone enough to downvote it: http://stackoverflow.com/questions/34360579/webpack-globalize-fails-build-when-set-to-production-mode-no-formatters-or-pars
@rxaviers I just reread your comment - the problem is not with globalize itself. Its with my application and the use of globaalize webpack plugin. When I build MY application with production:true in the GlobalizePlugin config then I get that error. Globalize itself is fine I'm sure
Well, I have probably found the issue: my code does not (yet) contain any formatters; code like this one:
Globalize.formatMessage("intro-1")()
(which is corresponding to the error message 'No formatters or parsers has been provided'.)
As soon as I add this code somewhere in the application, it starts working.
But when I use globalize with react (which is obviously also @harel's situation), my application may really not have any Globalize.formatMessage
calls. Because I may just use Globalize
as localizer for react-widgets
(http://jquense.github.io/react-widgets/docs/#/i18n) or I may format messages using react-globalize
module.
But when I check the output in 'release' mode, maybe this plugin is not suitable for usage with react-globalize, because only those messages get to 'globalize-compiled-data', which are used directly by a Globalize method. Is it true?
I have end up with the same issue when I use yours react-globalize-webpack-plugin
set writeMessages: true
, and there is no call for Globalize.formatMessage
.
What I really want to do, is just use globalize with webpack. And I have not succeeded without yours plugin. But the plugin seems to do more than I want, it tries to analyse the code and extracts only used messages. Which makes unable to write code like this one:
var key="intro-1";
console.log(Globalize.formatMessage(key)());
because the compilation fails... ReferenceError: key is not defined
.
Is it possible to skip this advanced features?
I can confirm the error goes away after using @adros trick of putting a formatMessage somewhere. The build completes without error. However, that means that 'messages' are not optional, they are required. As well, If I add a messages dir as per my config, and add one file per locale, I get json parsing errors unless i remove all spaces from the json file.
so this fails :
{
"en-GB": {
"message": "some message"
}
}
but this works:
{"en-GB":{"message":"some message"}}
And as well, I don't get the i18n
directory in my build/assets. Its just not there on build...
The json parsing errors appear on dev as well.
> webpack --config webpack.prod.config.js --progress
undefined:2
"en-GB": {
^
SyntaxError: Unexpected token
at Object.parse (native)
at Object.module.exports.readMessages (/home/harel/dev/app/ui/node_modules/globalize-webpack-plugin/util.js:42:17)
at new DevelopmentModePlugin (/home/harel/dev/app/ui/node_modules/globalize-webpack-plugin/DevelopmentModePlugin.js:17:42)
at GlobalizePlugin.apply (/home/harel/dev/app/ui/node_modules/globalize-webpack-plugin/index.js:22:35)
at Compiler.apply (/home/harel/dev/app/ui/node_modules/webpack/node_modules/tapable/lib/Tapable.js:164:16)
at OptionsApply.WebpackOptionsApply.process (/home/harel/dev/app/ui/node_modules/webpack/lib/WebpackOptionsApply.js:62:18)
at webpack (/home/harel/dev/app/ui/node_modules/webpack/lib/webpack.js:22:48)
at processOptions (/home/harel/dev/app/ui/node_modules/webpack/bin/webpack.js:152:17)
at Object.<anonymous> (/home/harel/dev/app/ui/node_modules/webpack/bin/webpack.js:192:1)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
npm ERR! Linux 3.13.0-73-generic
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "run" "build"
npm ERR! node v0.12.9
npm ERR! npm v2.14.9
npm ERR! code ELIFECYCLE
npm ERR! ui@1.0.0 build: `webpack --config webpack.prod.config.js --progress`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the ui@1.0.0 build script 'webpack --config webpack.prod.config.js --progress'.
npm ERR! This is most likely a problem with the ui package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! webpack --config webpack.prod.config.js --progress
npm ERR! You can get their info via:
npm ERR! npm owner ls ui
npm ERR! There is likely additional logging output above.
npm ERR! Please include the following file with any support request:
npm ERR! /home/harel/dev/app/ui/npm-debug.log
Sorry, i had production flag set to false when I tested just now. I tested again with production set to true, and it works still. The message files get bundled up in my app.js file though and not in the i18n directory as I specified in the output property.
Ok I resolved part of this: When specifying the output as "i18n_[locale].js" it does generate the files. As well, when specifying the output as the full path into the assets dir "assets/i18n/[locale].js" it does work as well and they are generated. There is still the problem where pretty json (with indentations) fails with invalid json error above. The same json as is, passes a json linter just fine as valid. So not sure why it fails here.
messages
is optional considering you're not using it (i.e., not using formatMessage
or messageFormatter
). Please, could you provide a gist with a reduced example that I can use to reproduce the problem you are facing?
the only thing I've done while having this problem is adding the plugin to my webpack config as described above, excluding the messages key. On dev mode it worked fine. But when setting production to true and running npm run build it failed. That is, until I tried the trick above which resolved it (i.e., adding messages and a formatMessage somewhere). Since then I've gone all in on globalizer and now am using the messages module and things are working fine. I'm not really sure how to dilute my app into a working 'failing' example at this point.
Gotcha, this error shows up when no Globalize code is being used in the source code. messages
is optional and this issue should be fixed.
I'm having the same issue with a webpack and react project. It seems that the production mode of the plugin can't see that I'm using a formatter and then crashes with an error message...
It seems as if the globalize-compiler is not able to figure out which formatters are used when the JS code is actually compiled by babel...
@matthiasfeist if you have a formatter being used in your code, you have a different issue. Please, file a new issue with context. Also make sure you have Globalize 1.1.x in place.
Thanks for the response. It was actually the issue with a version conflict :+1: thanks for the heads up!
Excellent and you're welcome.
I'm having the exact same issue. Using globalize with react-globalize. I am not using the message component.
@lochstar do you use any Globalize function or react-globalize component?
The only Globalize function I'm using is Globalize.locale(). I'm also using FormatCurrency, FormatDate, FormatNumber & FormatRelativeTime.
Since you're using react-components this bug shouldn't affect you. You should set the default locale via your webpack config, not Globalize.locale()
. That might be the reason.
It's set via webpack config as well. I use Globalize.locale()
in my code to change the locale via a select box.
If I remove the call, the error still persists when trying to build for production.
Hm, ok. So, please file a separate ticket providing a reduced example.
I've determined the following:
include Globalize
with reference in the code - production build passes
include Globalize
with no reference in the code - production build fails
include Globalize
and react-globalize
with no reference in the code - production build fails
include Globalize
and react-globalize
with reference in the code - production build passes
So production build works fine in both cases, as long as there's a direct call to Globalize
in the source. I shouldn't need to include this as I have react-globalize
components.
Any ideas? Is this a react-globalize
issue?
+1 same here
I really want to help you all, but it seems we're collecting so many different things for this issue.
This issue is supposed to track a bug that shows up when trying to use the plugin while no Globalize code is being used in the source code.
PS: react-globalize uses Globalize under the hoods, so using react-globalize messages and/or Globalize messages (.formatMessage) is equivalent.
If you have problems with the react-globalize-plugin, please file an issue on rxaviers/react-globalize-webpack-plugin. I have provided a react-globalize example here, so please use this example as a baseline for yours. File the issue with an example in place (feel free to file a PR with the example then).
If you have problems with this plugin (globalize-plugin) and it isn't the bug defined by this issue (using this plugin while no Globalize or react-globalize code is being used in the source code), please file a separate issue including an example. You can use this example as a baseline for yours.
If you are experiencing the bug defined here, PRs are welcome. The fix shouldn't be hard. I can provide assistance.
it also appears that in production mode that the require literally needs to be tied to a variable named "Globalize" in order for this error message to not appear. i.e.:
var Globalize = require( "globalize" ); Globalize.formatMessage( "Success" );
will succeed, but:
var i18n = require( "globalize" ); i18n.formatMessage( "Success" );
will fail with the "Error: No formatters or parsers has been provided" message
@AppSorcery you're correct, but this is a separate issue. The globalize-compiler is still pretty naive on that regard. It simply checks for Globalize
(code) instead of the name declared in the import (in which case the compiler would have to keep a table of the scopes and variable names to check for).
@lochstar, @brenwell, @AppSorcery, you could have experienced this bug react-globalize-webpack-plugin#14.
I've also had the same issue with production build $\node_modules\globalize-webpack-plugin\GlobalizeCompilerHelper.js:72 throw e; ^ Error: No formatters or parsers has been provided
It will work if I add the following somewhere in the app!
Globalize.formatMessage("someMessage");
Its actually very annoying issue since the workaround basically means we have to add lines in the code to call to formatMessage API for every single entry in our
FYI: we are not using react-globalize
Hi! Any new on this issue? I have the same problem
Sorry for beating a dead horse, but we are seeing this issue as well when building our app using webpack with production flag set to true:
Our app doesn't use messaging and just uses the number parsing feature of globalize.
Error: No formatters or parsers has been provided
We are including globalize with:
import Globalize from 'globalize';
Any suggestions?
This definitely needs fix. PRs are welcome. I can provide assistance.
@rxaviers hey, thanks for the quick reply. I see that dynamic locale loading has been brought up relating to this issue and was curious if you have a recommended way of doing that in an npm-webpack environment. The current example app with npm and webpack is really just good for one language but doesn't really do anything for those of us with use cases involving language pickers, etc. You've mentioned writing a custom {cldr: fn()} in the webpack config but does that mean if we want to select between 5 locales in the language picker, we'd need to pre-load all 5 locales in globalize?
Error: No formatters or parsers has been provided
I have the same problem.
@gehsekky no you wouldn't pre-load all 5 locales (into the browser all at once), you would look at the request headers (accepts language, e.g.) or some parameter you define in your request and load just that one locale (which would contain all of your localized messages including the localized text options for your language picker).
then if the user selects a different locale you change the header or parameter and perform a new request (you could try and do something clever and fetch the new language bundle from a cdn over ajax and completely update the client without hitting the server...but i haven't tried it yet).
Same EXACT issue with my code. If set to production mode, you get the error mentioned in the title. Seems like they are not going to fix this; apparently the issue has been around for two years now.
Same problem, I am using globalize-webpack-plugin
in a client app that references our own home-grown react formatter components, which in turn use our custom formatters library that calls Globalize
directly. No direct mention of Globalize
in the client app however. Any way around this? I prefer the idea of having webpack build only the formatters that are ultimately used, but globalize plugin can't yet handle this indirection.
This is the most annoying issue :)
Perhaps we could simply catch that exception (thrown by globalize-compiler) and console.warn
it in here instead. PRs are welcome... What are the potential impact? Warn (instead of throwing) on cases where this plugin is being used uselessly?
@darincardin and @casey-speer, may you push a sample repo with your issue at hand? I'll be happy to take a look and fix it.
What I'd like to happen is that if globalize
is used indirectly, globalize-webpack-plugin
would be able to find that usage and extract/compile formatters for it. E.g., in my client code I have
import NumberFormatter from 'myFormatterComponents/number';
const myComponent = ({number}) => (<span> Look at this number: <NumberFormatter value={number} /></span>);
and in a separate npm module myFormatterComponents/number.jsx
I have
import numberFormatter from 'myFormatters/number';
export const NumberFormatter = ({value}) => (<span>{numberFormatter(value)}</span>);
finally in another npm module myFormatters/number.js
:
import Globalize from 'globalize';
export const numberFormatter = (value) => { return Globalize.formatNumber(value) };
I just want to drop in globalize-webpack-plugin
in my client app and and have it extract/compile the necessary globalize
formatters for my entire app bundle, regardless of how they are included in the bundled code. (Kind of a contrived example, but having a separate formatters library is currently a requirement of our applications for various reasons).
Does this make sense or is it unreasonable? I think for this case it's not a 'useless' inclusion of the plugin, just that the globalize
formatters don't appear in first-party code from the perspective of the client app. I'd still want those formatter instances to be extracted/compiled. Maybe I'm misunderstanding some limitations here? Thanks!
@casey-speer I get it. May you create a q&r sample repo? It will be much easier.
Hi @casey-speer, this requires extra smarts to the globalize-compiler. Feel free to express your thoughts on how you think that could be doable. Specially, please read this https://github.com/globalizejs/globalize-compiler/issues/10.
Having said that, that seems a different topic and should be discussed elsewhere, not in this thread. Feel free to file an issue in globalize-compiler with your thoughts. Thanks.
@diligiant @rxaviers Yes I think this does turn out to be off-topic. I've read through that issue and a lot of the globalize
, gloablize-compiler
, and globalize-webpack-plugin
code and I have a better understanding of how all this works. My solution is going to be to generate a statically-analyzable set of formatters and either precompile them along with the runtime per locale or else feed them to the webpack plugin. Thanks for your help.
Having kind of the same issue as well..
node_modules\globalize-webpack-plugin\GlobalizeCompilerHelper.js:77 throw e; ^ Error: No formatters or parsers has been provided
However, adding a formatting function like Globalize.formatMessage("someMessage"); does not help. My webpack config looks like
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractCSS = new ExtractTextPlugin('allstyles.css');
const GlobalizePlugin = require("globalize-webpack-plugin");
module.exports = {
entry: {
main: './wwwroot/source/app.js',
vendor: [
"globalize",
"globalize/dist/globalize-runtime/number",
"globalize/dist/globalize-runtime/currency",
"globalize/dist/globalize-runtime/date",
"globalize/dist/globalize-runtime/message",
"globalize/dist/globalize-runtime/plural",
"globalize/dist/globalize-runtime/relative-time",
"globalize/dist/globalize-runtime/unit"
]
},
output: {
path: path.resolve(__dirname, 'wwwroot/dist'),
filename: 'bundle.js',
publicPath: 'dist/'
},
plugins: [
extractCSS,
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default'],
//Globalize: 'globalize'
}),
new GlobalizePlugin({
production: true, // true: production, false: development
developmentLocale: "en", // locale to be used for development.
supportedLocales: ["en", "nl", "fr"], // locales that should be built support for.
output: "globalize-compiled-data-[locale].[hash].js", // build output.
tmpdirBase: ".", // optional for non create-react-apps
}),
].concat([
new webpack.optimize.UglifyJsPlugin()
]),
module: {
rules: [
{
test: /\.css$/,
use: extractCSS.extract({
fallback: 'style-loader',
use: 'css-loader?minimize'
})
},
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff"
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "file-loader"
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
}
};
Versions:
Following the examples provided, using globalize-webpack-plugin 0.2 and globalize 1.1.0-rc.7 (as well as rc.5 and rc.6), when setting
production:true
I'm getting the following error below:Config
Error at
npm run build