From a8de2def91ebe156c10841b4eb2e45c6495e0ce6 Mon Sep 17 00:00:00 2001 From: Cory McDonald Date: Thu, 21 Dec 2017 21:28:46 -0600 Subject: [PATCH 1/2] Add typescript installer --- docs/typescript.md | 38 +++--------------- lib/install/angular.rb | 19 +-------- lib/install/config/webpacker.yml | 1 + lib/install/examples/react/tsconfig.json | 20 ++++++++++ .../examples/typescript/hello_typescript.ts | 4 ++ .../{angular => typescript}/tsconfig.json | 0 lib/install/typescript.rb | 40 +++++++++++++++++++ lib/tasks/installers.rake | 24 ++++++++--- lib/tasks/webpacker.rake | 3 +- 9 files changed, 93 insertions(+), 56 deletions(-) create mode 100644 lib/install/examples/react/tsconfig.json create mode 100644 lib/install/examples/typescript/hello_typescript.ts rename lib/install/examples/{angular => typescript}/tsconfig.json (100%) create mode 100644 lib/install/typescript.rb diff --git a/docs/typescript.md b/docs/typescript.md index c85416baf..a6f87d9bc 100644 --- a/docs/typescript.md +++ b/docs/typescript.md @@ -3,43 +3,15 @@ ## Typescript with React -1. Setup react using Webpacker [react installer](#react). Then add required depedencies -for using typescript with React: +1. Setup react using Webpacker [react installer](#react). Then run the typescript installer ```bash -yarn add ts-loader typescript @types/react @types/react-dom +bundle exec rails webpacker:install:typescript +yarn add @types/react @types/react-dom ``` -2. Add a `tsconfig.json` to project root: - -``` json -{ - "compilerOptions": { - "declaration": false, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "lib": ["es6", "dom"], - "module": "es6", - "moduleResolution": "node", - "sourceMap": true, - "jsx": "react", - "target": "es5" - }, - "exclude": [ - "**/*.spec.ts", - "node_modules", - "vendor", - "public" - ], - "compileOnSave": false -} -``` - -3. Finally add `.tsx` to the list of extensions in `config/webpacker.yml` -and rename your generated `hello_react.js` using react installer -to `hello_react.tsx` and make it valid typescript and now you can use -typescript, JSX with React. - +2. Rename the generated `hello_react.js` to `hello_react.tsx`. Make the file valid typescript and +now you can use typescript, JSX with React. ## HTML templates with Typescript and Angular diff --git a/lib/install/angular.rb b/lib/install/angular.rb index b000535d8..d096cdd34 100644 --- a/lib/install/angular.rb +++ b/lib/install/angular.rb @@ -1,27 +1,12 @@ require "webpacker/configuration" -say "Copying angular loader to config/webpack/loaders" -copy_file "#{__dir__}/loaders/typescript.js", Rails.root.join("config/webpack/loaders/typescript.js").to_s - -say "Adding typescript loader to config/webpack/environment.js" -insert_into_file Rails.root.join("config/webpack/environment.js").to_s, - "const typescript = require('./loaders/typescript')\n", - after: "require('@rails/webpacker')\n" - -insert_into_file Rails.root.join("config/webpack/environment.js").to_s, - "environment.loaders.append('typescript', typescript)\n", - before: "module.exports" - say "Copying angular example entry file to #{Webpacker.config.source_entry_path}" copy_file "#{__dir__}/examples/angular/hello_angular.js", "#{Webpacker.config.source_entry_path}/hello_angular.js" say "Copying hello_angular app to #{Webpacker.config.source_path}" directory "#{__dir__}/examples/angular/hello_angular", "#{Webpacker.config.source_path}/hello_angular" -say "Copying tsconfig.json to the Rails root directory for typescript" -copy_file "#{__dir__}/examples/angular/tsconfig.json", "tsconfig.json" - say "Installing all angular dependencies" -run "yarn add typescript ts-loader core-js zone.js rxjs @angular/core @angular/common @angular/compiler @angular/platform-browser @angular/platform-browser-dynamic" +run "yarn add core-js zone.js rxjs @angular/core @angular/common @angular/compiler @angular/platform-browser @angular/platform-browser-dynamic" -say "Webpacker now supports angular and typescript 🎉", :green +say "Webpacker now supports angular 🎉", :green diff --git a/lib/install/config/webpacker.yml b/lib/install/config/webpacker.yml index f1bf26792..4183fea48 100644 --- a/lib/install/config/webpacker.yml +++ b/lib/install/config/webpacker.yml @@ -18,6 +18,7 @@ default: &default - .erb - .js - .jsx + - .tsx - .ts - .vue - .sass diff --git a/lib/install/examples/react/tsconfig.json b/lib/install/examples/react/tsconfig.json new file mode 100644 index 000000000..7425c2b4b --- /dev/null +++ b/lib/install/examples/react/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "declaration": false, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es6", "dom"], + "module": "es6", + "moduleResolution": "node", + "sourceMap": true, + "target": "es5", + "jsx": "react" + }, + "exclude": [ + "**/*.spec.ts", + "node_modules", + "vendor", + "public" + ], + "compileOnSave": false +} diff --git a/lib/install/examples/typescript/hello_typescript.ts b/lib/install/examples/typescript/hello_typescript.ts new file mode 100644 index 000000000..e3988884a --- /dev/null +++ b/lib/install/examples/typescript/hello_typescript.ts @@ -0,0 +1,4 @@ +// Run this example by adding <%%= javascript_pack_tag 'hello_typescript' %> to the head of your layout file, +// like app/views/layouts/application.html.erb. + +console.log('Hello world from typescript'); diff --git a/lib/install/examples/angular/tsconfig.json b/lib/install/examples/typescript/tsconfig.json similarity index 100% rename from lib/install/examples/angular/tsconfig.json rename to lib/install/examples/typescript/tsconfig.json diff --git a/lib/install/typescript.rb b/lib/install/typescript.rb new file mode 100644 index 000000000..0643dfb2c --- /dev/null +++ b/lib/install/typescript.rb @@ -0,0 +1,40 @@ +require "webpacker/configuration" + +additional_packages = "" +example_source = "typescript" + +# Additional configuration is required for React projects +package_json = Rails.root.join("package.json") +if File.exist?(package_json) + package = JSON.parse(File.read(package_json)) + package["dependencies"] ||= {} + + if package["dependencies"].keys.include?("react") + additional_packages = "@types/react @types/react-dom" + example_source = "react" + end +end + +say "Copying typescript loader to config/webpack/loaders" +copy_file "#{__dir__}/loaders/typescript.js", Rails.root.join("config/webpack/loaders/typescript.js").to_s + +say "Adding typescript loader to config/webpack/environment.js" +insert_into_file Rails.root.join("config/webpack/environment.js").to_s, + "const typescript = require('./loaders/typescript')\n", + after: "require('@rails/webpacker')\n" + +insert_into_file Rails.root.join("config/webpack/environment.js").to_s, + "environment.loaders.append('typescript', typescript)\n", + before: "module.exports" + +say "Copying tsconfig.json to the Rails root directory for typescript" +copy_file "#{__dir__}/examples/#{example_source}/tsconfig.json", "tsconfig.json" + +say "Copying the example entry file to #{Webpacker.config.source_entry_path}" +copy_file "#{__dir__}/examples/typescript/hello_typescript.ts", + "#{Webpacker.config.source_entry_path}/hello_typescript.ts" + +say "Installing all typescript dependencies" +run "yarn add typescript ts-loader #{additional_packages}" + +say "Webpacker now supports typescript 🎉", :green diff --git a/lib/tasks/installers.rake b/lib/tasks/installers.rake index c5b9cec9a..57274c970 100644 --- a/lib/tasks/installers.rake +++ b/lib/tasks/installers.rake @@ -4,20 +4,34 @@ installers = { "React": :react, "Vue": :vue, "Erb": :erb, - "Coffee": :coffee + "Coffee": :coffee, + "Typescript": :typescript }.freeze +dependencies = { + "Angular": [:typescript] +} + namespace :webpacker do namespace :install do installers.each do |name, task_name| desc "Install everything needed for #{name}" task task_name => ["webpacker:verify_install"] do template = File.expand_path("../install/#{task_name}.rb", __dir__) - if Rails::VERSION::MAJOR >= 5 - exec "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{template}" - else - exec "#{RbConfig.ruby} ./bin/rake rails:template LOCATION=#{template}" + base_path = + if Rails::VERSION::MAJOR >= 5 + "#{RbConfig.ruby} ./bin/rails app:template" + else + "#{RbConfig.ruby} ./bin/rake rails:template" + end + + dependencies[name] ||= [] + dependencies[name].each do |dependency| + dependency_template = File.expand_path("../install/#{dependency}.rb", __dir__) + system "#{base_path} LOCATION=#{dependency_template}" end + + exec "#{base_path} LOCATION=#{template}" end end end diff --git a/lib/tasks/webpacker.rake b/lib/tasks/webpacker.rake index 0320a5ad6..46506e48a 100644 --- a/lib/tasks/webpacker.rake +++ b/lib/tasks/webpacker.rake @@ -12,7 +12,8 @@ tasks = { "webpacker:install:angular" => "Installs and setup example Angular component", "webpacker:install:elm" => "Installs and setup example Elm component", "webpacker:install:erb" => "Installs Erb loader with an example", - "webpacker:install:coffee" => "Installs CoffeeScript loader with an example" + "webpacker:install:coffee" => "Installs CoffeeScript loader with an example", + "webpacker:install:typescript" => "Installs Typescript loader with an example" }.freeze desc "Lists all available tasks in Webpacker" From 3f7c26682e2d73f24e00f89564faa1e9fbf2e0a9 Mon Sep 17 00:00:00 2001 From: Cory McDonald Date: Fri, 22 Dec 2017 13:38:51 -0600 Subject: [PATCH 2/2] Add new tsx extension to test_app --- test/test_app/config/webpacker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_app/config/webpacker.yml b/test/test_app/config/webpacker.yml index 6ca3e8f3a..fb7cba0bd 100644 --- a/test/test_app/config/webpacker.yml +++ b/test/test_app/config/webpacker.yml @@ -20,6 +20,7 @@ default: &default - .erb - .js - .jsx + - .tsx - .ts - .vue - .sass