babel v6 + react-intl v2 + webpack extraction of messages to file - json

I would like to extract the messages from the source code to a JSON file, using Babel v6, react-intl v2, and webpack. It's all compiling fine, but not extracting anything. How do I make v2 of react-intl properly extract the messages?
There's an option messagesDir:
I've tried:
new file .babel.rc from here: https://github.com/yahoo/babel-plugin-react-intl/issues/23 – probably misspelt name, should be .babelrc.
new file .babelrc:
{
"extra": {
"react-intl": {
"messagesDir": "./i18n",
"enforceDescriptions": true
}
}
}
With webpack config
{ test: /\.js$/,
loader: 'babel-loader',
query: {
// react needed for JSX syntax
// es2015 needed for modules
// stage0 needed to do splats (...variable)
presets: ['react', 'es2015', 'stage-0'],
// react-intl extracts i18n messages to a shared file
// add-module-exports removes the need to do `require('a').default`
plugins: ['react-intl', 'add-module-exports'],
cacheDirectory: true
},
exclude: /node_modules|bower_components/
},
gives: "index.js: Unknown option: /.babelrc.extra" as the error message.
I've tried adding the above extra property to the webpack configuration above, too. It gives a very similar error message.
Versions:
✗ npm ls | grep "intl"
├─┬ babel-plugin-react-intl#2.0.0
│ └── intl-messageformat-parser#1.2.0
├── intl#1.0.1
├── intl-locales-supported#1.0.0
├── intl-messageformat#1.2.0
├─┬ react-intl#2.0.0-pr-3
│ ├── intl-format-cache#2.0.4

The answer is to use a very custom webpack syntax:
Syntax is thus:
5 plugins: [
- ['react-intl', {
6 'messagesDir': './i18n'
6 }], 'add-module-exports']

Related

TypeORM: "No migrations pending" when attempting to run migrations manually

I have a new web app and I've written a migrator to create a user table. However, no matter what I try, typeorm does not appear to find this migrator and hence, does not run it.
My file structure (other files/folders not shown):
├── Server
│ ├── dist
| | ├── Migrations
| | | ├── 1234567891234567890-AddUserTable.js
| | | ├── 1234567891234567890-AddUserTable.js.map
| | | ├── 1234567891234567890-AddUserTable.d.ts
│ ├── src
| | ├── Migrations
| | | ├── 1234567891234567890-AddUserTable.ts
| | ├── app.module.ts
app.module.ts
#Module({
imports: [
ConfigModule.forRoot({ envFilePath: '.env' }),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'mysql',
host: configService.get('TYPEORM_HOST'),
port: +configService.get<number>('TYPEORM_PORT'),
username: configService.get('TYPEORM_USERNAME'),
password: configService.get('TYPEORM_PASSWORD'),
database: configService.get('TYPEORM_DATABASE'),
synchronize: configService.get('TYPEORM_SYNCHRONIZE'),
entities: [__dirname + '/**/*.entity{.ts,.js}'],
migrations: [__dirname + '/Migrations/**/*.js'],
migrationsRun: false,
cli: {
migrationsDir: './Migrations',
},
}),
inject: [ConfigService],
}),
],
controllers: [],
providers: [],
})
export class AppModule {
constructor(private connection: Connection) {}
}
In order to run this, in my console window, I type: nest start in order get my Server started.
Then, I run npx typeorm migration:run which I get:
query: SELECT * FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = 'myDB' AND `TABLE_NAME` = 'migrations'
query: SELECT * FROM `myDB`.`migrations` `migrations` ORDER BY `id` DESC
No migrations are pending
If I look in my DB, I see a migrations table with no entries inside.
I have tried to delete my migrator file and create it again with a more recent timestamp and that does not work either.
npx typeorm migration:create -n "MyMigratorName"
Any help would be greatly appreciated.
For anyone coming here for help:
The config above mentions migrations to be found in js files:
migrations: [__dirname + '/Migrations/**/*.js'],
However from the folder structure its clear that migrations are written in ts files not js.
To run migrations from ts follow the officially recommended way described here:
https://github.com/typeorm/typeorm/blob/master/docs/using-cli.md#if-entities-files-are-in-typescript
Also in that case don't forget to update the migrations blob to be ts:
migrations: [__dirname + '/Migrations/**/*.ts'],
If you want to run the migrations from js files you will have to provide the location to be from dist folder after the ts files have been compiled to js form.
Typeorm only loads migration from files with js extension,
In the ormconfig file where you set up your connection;
{
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "test",
"password": "test",
"database": "test",
"entities": ["entity/*.js"],
"migrationsTableName": "custom_migration_table",
"migrations": ["migration/*.js"],
"cli": {
"migrationsDir": "migration"
}
}
"migrations": ["migration/*.js"] - indicates that typeorm will load migrations from the given "migration" directory.
if your migration folder is stored in a dist or src directory,
"migrations": ["migration/*.js"] will now be "migrations": ["dist/migration/*.js"] or
"migrations": ["src/migration/*.js"], the * means any migration filename.
Just make sure whatever directory/directories placed here ["migration/*.js"] leads to where your migration file(s) are
"migrationsDir": "migration"- indicates that the CLI must create new migrations in the "migration" directory. so whatever directory you specify here is where your migration files will be created.
Please note that if your migration files have typescript extensions(.ts), you have to compile your migrations files into javascript files if not typeorm will not find them.
In addition to answer given by #Upka Uchechi
If you're using typescript, you need to run the following commands
$ npm run build # This will compile the typescript files into JavaScript files
$ npm run typeorm -- migration:run
To give a bit more context.
If your configuration files are lookated at <PROJECT ROOT>/db-migrations, the build command above should move the compiled JavaScript files to <PROJECT ROOT>/dist/db-migrations. For that, your configuration file would look like this
...
"migrations": ["dist/db-migrations/*.js"],
...

How to prevent optimization of text! and json! plugins on r.JS tool from Require.JS?

Already seen many topics here but none of the pointed solutions worked.
When optimizing my project, R.js is failing to handle this json! plugin dependency on one of my modules.
Error message:
Tracing dependencies for: app/productApp
TypeError: errback is not a function
In module tree:
app/productApp
blah
json
My r.js build config file:
define([
'productApp',
'json!blah'
], function(...){...}
and here is my r.js config file:
({
name: 'app/productApp',
out: '../app.js',
optimize: 'uglify2',
findNestedDependencies: true,
inlineJSON: false,
inlineText: false,
exclude: [ 'json!blah' ]
)}
I've already tried all possible ways, such as an exclude on the r.js config file, or and adding '!bust' at the end of the dependency list, but no luck.
Require.js / R.js version: 2.2.0
One detail: I'm running r.js through node package.json script, triggered by maven.
Thoughts?
Found the solution. It turns out that the paths to the json and text libraries were missing from require config file. (it can't be just made 'empty:' within r.js build config file).
This then would fix the issue:
...
paths: {
'text': 'lib/text',
'json': 'lib/json',
...
},
exclude: {
'json!blah'
}

Webpack dev server configuration refuse to work with full path to index

Hello I am trying to understand why does webpack dev server refuse to work with full path to my index.js. (I am using webpack with babel to build reactJS.)
At the moment my webpack.config is located in the same directory as my index.js file and due to that the declaration of the entry point of my index.js is just "./index". Here is how my webpack.config looks like:
module.exports = {
devtool: 'inline-source-map',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
resolve: {
extensions: ['', '.js']
},
module: {
loaders: [{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
include: __dirname
}]
}};
With this configuration my project is build by babel and works just fine on the server!
My problem comes when I tried to specify a full path of my index.js entry point. I need that because I want to externalize the webpack and it's configuration from my FE code. To be sure that it will work I first tried not to rely that webpack.config and index.js are in the same directory but to specify the path of the index as full path name:
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'D:/projects/myProject/index'
]
With this config babel seem to be able to navigate to the index.js and start compiling it, but it does encounter an unexpected (for me) error during the parse:
ERROR in D:/projects/myProject/index.js
Module parse failed: D:/projects/myProject/index.js Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import 'babel-core/polyfill';
|
| import React from 'react';
# multi main
What do I miss, why webpack makes difference between relatively configured index.js and full path one?
(I made sure that the full path is correct)
Thanks!
After a bit annoying investigation it appeared that my problem is specifying the Windows drives in uppercase. For some reason it appear that the index.js location full path should start with lowercase drive letter!
Hopefully this experience may be helpful to others.
Try using:
d:/Folder1/folder2/index.js
instead of
D:/Folder1/folder2/index.js

Why does main-bower-files filter some packages?

I've got a gulp task which is intended to copy bower dependencies to another folder, but only a subset of the dependencies are being matched.
Here's a simplified version of the task which just prints out the matching paths:
gulp.task('list-dependencies',function() {
gulp.src(mainBowerFiles('**/*'), { base: './bower_components' })
.pipe($.print());
});
Here's the bower.json file contents:
bower.json
{
"name": "app",
"private": true,
"dependencies": {
"bootstrap": "3.0.0",
"jquery": "1.10.2",
"modernizr": "~2.8.3",
"angular": "~1.4.4",
"angular-ui": "~0.4.0",
"angular-route": "~1.4.4"
}
}
Here's a listing of the bower_components folder:
$ ls bower_components/
angular angular-route angular-ui bootstrap jquery modernizr
outut:
[13:30:08] Starting 'list-dependencies'...
[13:30:08] Finished 'list-dependencies' after 27 ms
[gulp] bower_components\jquery\jquery.js
[gulp] bower_components\angular\angular.js
[gulp] bower_components\angular-route\angular-route.js
[gulp] bower_components\bootstrap\dist\js\bootstrap.js
[gulp] bower_components\bootstrap\dist\css\bootstrap.css
As you can see, angular-ui and modernizr aren't listed. Can someone explain why this is happening?
Bower has a concept of defining "main" files within a bower.json. The packages that were missed were due to the fact that these packages didn't contain a bower.json file which defined the main files. To get the main-bower-files plugin to work, you have to define overrides either within your bower file or as a parameter to main-bower-files.

TypeError: Handlebars.templates is undefined

I'm working with yeoman, gruntjs and handlebars.js, but my template don't load anymore with the following error in firebug:
TypeError: Handlebars.templates is undefined
var compiledTemplate = Handlebars.templates['cheatsheet.hbs'];
Handlebars.JS
In my package.json, I got:
"grunt-contrib-handlebars": "~0.5.9" // previously used ~0.5.8
Gruntjs tasks
Task: handlebars
I'm compiling .hbs to .hbs.js files:
handlebars: {
compile: {
options: {
namespace: 'JST'
},
files: {
'<%= yeoman.app %>/scripts/cheatsheet.hbs.js':
[ '<%= yeoman.app %>/templates/{,*/}*.hbs'] ,
}
}
},
Task: watch
I added the following in the watch section:
watch: {
// recompile handlebars' templates when they change
// #see: https://github.com/yeoman/yeoman/wiki/Handlebars-integration
handlebarsCompile: {
files: ['<%= yeoman.app %>/templates/{,*/}*.hbs'],
tasks: ['handlebars:compile']
},
handlebarsReload: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.hbs.js'],
tasks: ['livereload']
},
Tasks: grunt server and grunt build
I added the following entry to both task:
'handlebars:compile',
HTML file
I'm importing handlebars, the template and the script to inflate it:
<script src="components/handlebars.js/dist/handlebars.runtime.js"></script>
<script src="scripts/cheatsheet.hbs.js"></script>
<script src="scripts/main.js"></script>
Compiled template: cheatsheet.hbs.js
In the top lines, I got this:
this["JST"]["app/templates/cheatsheet.hbs"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
Template inflater: main.js
To inflate my compiled template I'm using this:
var compiledTemplate = Handlebars.templates['cheatsheet.hbs'];
Question
So what's the matter here Handlebars.templates array? Why is not created? How to create it?
More info
I created a gist to hold the full Gruntfile.js and cheatsheet.hbs.js.
After reading the section on precompiler usage:
If using the precompiler's normal mode, the resulting templates will
be stored to the Handlebars.templates object using the relative
template name sans the extension. These templates may be executed in
the same manner as templates.
I went on to debug the compiled template.
Debugging
Manual compilation
As I installed handlebars global, I can run compile templates manually. This wasn't enough, and I had to update the live file:
handlebars ./app/templates/cheatsheet.hbs -f ./app/scripts/cheatsheet.hbs.js # compile
cp ./app/scripts/cheatsheet.hbs.js ./.tmp/scripts/cheatsheet.hbs.js # update .tmp's template
Comparing with what grunt outputs
I saw that compiled template where different, the template reference doesn't occur in the same variable.
Manually compiled vs. Grunt compiled
- (function() {
- var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
- templates['cheatsheet.hbs'] = template(function (Handlebars,depth0,helpers,partials,data) {
+ this["JST"] = this["JST"] || {};
+
+ this["JST"]["cheatsheet.hbs"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
So I went to my task and saw
namespace: 'CHSH.Templates'
So I read the doc about namespace, and I wasn't using the right namespace in main.js
Solution
Step #1: Updating package
First globally:
sudo npm update handlebars -g
Then locally
bower update
I got some message about handlebars, but doesn't block:
Please note that
requires handlebars.js ~1.0.11
Resolved to handlebars.js v1.0.0, which matches the requirement
defined in the project's component.json. Conflicts may occur.
Step #2: Update Gruntfile.js
I set the namespace to CHSH.Templates (cf. doc about namespace) ;
I updated the files option to compile the *.hbs template from the app/templates directory to the .tmp/scripts/ and
app/scripts directories;
handlebars: {
compile: {
options: {
namespace: 'CHSH.Templates'
},
files: [{
expand: true,
cwd: '<%= yeoman.app %>/templates',
src: '*.hbs',
dest: '<%= yeoman.app %>/scripts/',
ext: '.hbs.js'
},
{
expand: true,
cwd: '<%= yeoman.app %>/templates',
src: '*.hbs',
dest: '.tmp/scripts/',
ext: '.hbs.js'
}
]
}
}
I also edited to watch task to look after scripts/{,*/}*.js.
Step #3: Update main.js
Then I updated the namespace to match what I declared in my Gruntfile.js
- var compiledTemplate = Handlebars.templates['cheatsheet.hbs'];
+ var compiledTemplate = CHSH.Templates['app/templates/cheatsheet.hbs'];