I am using Angular 4.1.3 with Rails 5.1
I am trying to implement the app component and if I use template and write my html, everything works, but I want to use templateUrl.
Here is my component.
import { Component } from '#angular/core';
#Component({
selector: 'app',
templateUrl: './app.component.html'
})
export class AppComponent {}
And this is my file structure
├── app
| ├── app.component.html
| └── app.component.ts
| └── app.module.ts
I understand that in the #Component you can add moduleId: module.id but I thought this is no longer needed in angular 4.1.3.
If I do add it, it tells me:
moduleId should be a string in "AppComponent"
I also thought that if you do not include the moduleId angular just grabs from root directory, but if I do an absolute path, it should work right?
If you guys could help, that would be awesome.
I am assuming you're using the new webpacker-gem in your rails project!
There is a description of how to use templateUrl with it here in the documentation: Use HTML templates with Typescript and Angular
If you would like to keep templateUrl you could use angular2-template-loader webpack plugin:
# add plugins to project
yarn add angular2-template-loader raw-loader
and configure it:
# edit config/webpack/loaders/angular.js with
module.exports = {
test: /.ts$/,
loaders: ['ts-loader', 'angular2-template-loader'],
exclude: [/\.(spec|e2e)\.ts$/]
}
# create a new loader for htmls config/webpack/loaders/html.js
module.exports = {
test: /\.(html)$/,
loader: 'raw-loader',
exclude: /\.async\.(html)$/
}
Related
I'm developing a legacy ASP.NET MVC 5 project which still uses ASP.NET Bundling and Minification. I'm interested in switching to Gulp or Grunt, because I need to save source maps for my js files.
It seems easy to generate a minified script bundle with Gulp or Grunt, but what I do not understand yet is the recommended setup for loading single js files when debugging and minified bundles in production. I guess it would be quite easy to generate a razor view for including the scripts as part of my Grunt / Gulp compilation process, but it feels like re-inventing the wheel.
For instance, in ASP.NET MVC i can write something like this:
#Scripts.Render("~/bundles/MyJSBundle")
and it will automatically load separate js files in development and a single script bundle in production. What is the easiest way achieve this with Gulp or Grunt?
Short answer:
Typically when using Grunt you generate two builds - one for "dev" (development) and another for "dist" (distribution/production). Whereby for the scenario you've described;
Both the "dev" and "dist" builds generate a single concatenated/minified file version (e.g. bundle.min.js) derived from multiple source .js files.
However, only the "dev" build generates an additional Source Map file(s), that holds information about your original .js files, for the purpose of debugging during the development lifecycle.
Grunt plugins, such as grunt-processhtml, provide a way to update any links to .js assets in the .html file. For example, let's say your source .html contains these two links;
<script src="js/a.js"/>
<script src="js/b.js"/>
They can be substituted during the "dist" and/or "dev" build step to the following single <script> element:
<script src="dir/bundle.min.js"/>
Example demo:
The following somewhat contrived example demonstrates how you may approach your requirement using Grunt.
Let's say our initial project directory is structured as follows:
project
├── Gruntfile.js
├── node_modules
│ └── ...
├── package.json
└── src
├── index.html
└── js
├── a.js
└── b.js
Note, in the src directory we have a single index.html file, and two .js files in the js directory.
In the contents of index.html shown below it contains two <script> elements, each one referencing a .js file.
project/src/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>demo</title>
</head>
<body>
<!--build:js js/bundle.min.js-->
<script src="js/a.js"></script>
<script src="js/b.js"></script>
<!--/build-->
</body>
</html>
Note, the custom HTML comments encasing both <script> elements. These custom HTML comments are utilized by grunt-processhtml. The part that reads; js/bundle.min.js in the comment essentially defines the new pathname to be used.
Let's consider the following Gruntfile.js configuration:
Gruntfile.js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-processhtml');
grunt.initConfig({
// 1. Concatenate .js files.
concat: {
dist: {
src: [
'src/js/a.js',
'src/js/b.js'
],
dest: './dist/js/bundle.min.js'
},
dev: {
options: {
sourceMap: true
},
src: [
'src/js/a.js',
'src/js/b.js'
],
dest: './dev/js/bundle.min.js'
}
},
// 2. Minify .js files.
uglify: {
dist: {
files: {
'./dist/js/bundle.min.js': './dist/js/bundle.min.js' // dest : src
}
},
dev: {
options: {
mangle: false,
sourceMap: true,
sourceMapIn: './dev/js/bundle.min.js.map'
},
files: {
'./dev/js/bundle.min.js': './dev/js/bundle.min.js' // dest : src
}
}
},
// 2. Process .html file.
processhtml: {
dist: {
files: {
'./dist/index.html': './src/index.html' // dest : src
}
},
dev: {
files: {
'./dev/index.html': './src/index.html' // dest : src
}
}
}
});
grunt.registerTask('default', ['dist', 'dev']);
grunt.registerTask('dist', [
'concat:dist',
'uglify:dist',
'processhtml:dist'
]);
grunt.registerTask('dev', [
'concat:dev',
'uglify:dev',
'processhtml:dev'
]);
};
Explanation of Gruntfile.js:
In addition to the previously mentioned grunt-processhtml plugin the following two are also utilized in this example:
grunt-contrib-concat - for concatenating the two .js files.
grunt-contrib-uglify - for minifying the .js file.
Note: There are other plugins available for these types of task. I have chosen these additional two plugins for the purpose of this demonstration.
Each of the three Tasks (concat, uglify, and processhtml) contain two separate Targets named dist and dev. The main differences in each Target are:
Different dest (destination) paths for the resultant generated .jsfile(s).
For the concat:dev and uglify:dev Targets its options object defines the configuration for the resultant Source Map file.
At the end of Gruntfile.js three different grunt.registerTask() have been defined. Each one defines a taskList that essentially defines which Task and Target to run in the order specified.
For example consider the following registered task named dist:
grunt.registerTask('dist', [
'concat:dist',
'uglify:dist',
'processhtml:dist'
]);
When running grunt dist via the command line Grunt essentially invokes this Task, which subsequently performs the following in this order:
Firstly, runs the dist Target defined in the concat Task.
Then runs the dist Target defined in the uglify Task.
Finally, runs the dist Target defined in the processhtml Task.
Running Gruntfile.js (above) and its output
Running the following command via the command line:
grunt dev
outputs the following additional assets to the project directory:
project
├── ...
├── dev
│ ├── index.html
│ └── js
│ ├── bundle.min.js
│ └── bundle.min.js.map
└── ...
As you can see it has:
Created a new dev folder in the root of the project directory.
The two <script> elements originally defined in project/src/index.html have been substituted in the newly generated project/dev/index.html with a single <script> tag as follows:
<script src="js/bundle.min.js"></script>
Both files; project/src/js/a.js and project/src/js/b.js, have been concatenated and minified in the resultant project/dev/js/bundle.min.js.
The following source map file has been generated; project/dev/js/bundle.min.js.map. This file essentially maps back to the original project/src/js/a.js and project/src/js/b.js files.
Running the following command via the command line:
grunt dist
outputs the following additional assets to the project directory:
project
├── ...
├── dist
│ ├── index.html
│ └── js
│ └── bundle.min.js
└── ...
As you can see this time it has;
Created a dist folder in the root of the project directory.
Again, the two <script> elements originally defined in project/src/index.html have been substituted in the newly generated project/dist/index.html with a single <script> tag (as per the aforementioned dev Task).
Again, both files; project/src/js/a.js and project/src/js/b.js, have been concatenated and minified in the resultant project/dist/js/bundle.min.js.
However, the main notable difference is that NO source map file has been created.
Running the following command via the command line:
grunt
will produce both the outputs defined in the previous steps 1 and 2.
I'm trying to add TypeScript to an existing VueJS + Rails app. I cloned this demo (https://github.com/gbarillot/rails-vue-demo-app) then followed the instructions from https://github.com/rails/webpacker
$ bundle exec rails webpacker:install:vue
$ bundle exec rails webpacker:install:typescript
I then modified config/webpack/loaders/typescript.js as described here.
Everything seems to compile, but when I go into my "home" view and change the script to typescript:
<script lang="ts">
import Layout from '../shared/layout';
export default {
components: {
Layout
}
}
</script>
I get the following error:
Failed to compile.
/Users/matt/projects/rails-vue-demo-app/app/javascript/packs/components/home/index.vue.ts
[tsl] ERROR in /Users/matt/projects/rails-vue-demo-app/app/javascript/packs/components/home/index.vue.ts(13,20)
TS2307: Cannot find module '../shared/layout'.
Why can I no longer find the layout file when typescript is enabled?
I remember running into a similar problem for presentational components. Try adding an empty export in shared/layout so typescript can pick it up:
<script lang="ts">
export default {}
</script>
any idea how to deal with that ? I mean jquery-ui seems not to be amd and I don't know how to manage that , any idea ?
jquery-ui-dist and jquery-ui-bundle do not seem to be maintained by the jquery-ui team. After jquery-ui v1.12 Its possible to use the official jquery-ui package from npm with webpack.
Update jquery-ui to 1.12 by updating package.json and npm install.
Then you can require each widget like this.
require("jquery-ui/ui/widgets/autocomplete");
require("jquery-ui/ui/widgets/draggable");
If you have used require("jquery-ui") before you need to replace it with separate imports for each widget. I think the new way is better because it will bundle only the code for the widget we need to use.
See documentation on using the 1.12 official npm package.
For some reason jquery-ui didn't play nice with webpack. I had to require jquery-ui-bundle instead.
npm i -S jquery-ui-bundle
and then require it after jquery e.g.
require('jquery');
require('jquery-ui-bundle');
youre in luck I did this just that yesterday, it's rather easy.
npm install --save jquery jquery-ui
Make sure that you have jquery aliased to resolve with the plugin in the webpack.config.js
...
plugins: [
new webpack.ProvidePlugin({
"$":"jquery",
"jQuery":"jquery",
"window.jQuery":"jquery"
}),
...
Then include two aliases in the webpack.config.js
The node_modules folder
The jquery-ui folder
``````
resolve : {
alias: {
// bind version of jquery-ui
"jquery-ui": "jquery-ui/jquery-ui.js",
// bind to modules;
modules: path.join(__dirname, "node_modules"),
Make sure that jquery gets loaded first in your app startup file.
var $ = require("jquery"),
require("jquery-ui");
If you need to use a theme configure the css-loader and the file-loader. Don't forget to npm install those loaders.
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" },
{ test: /\.(jpe?g|png|gif)$/i, loader:"file" },
And use in your app startup file.
require("modules/jquery-ui/themes/black-tie/jquery-ui.css");
require("modules/jquery-ui/themes/black-tie/jquery-ui.theme.css");
webpack-jquery-ui
webpack-jquery-ui
- use this plugin, e.g. if you use Rails 5, run
yarn add webpack-jquery-ui
When jQuery UI plugin starts, it checks if jquery provided, so
Add this code to your webpacker configuration file (shared.js - if you use it with Rails 5)
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery'",
"window.$": "jquery"
})
]
Add these lines into your app code.
require('webpack-jquery-ui');
require('webpack-jquery-ui/css');
to fix ActionController::InvalidAuthenticityToken in jquery.ajax
You have to pass an authenticity_token parameter with all your PUT, POST and DELETE requests.
To do that you can usually fetch it from the header with $('[name="csrf-token"]')[0].content
So your request would look something like:
var that = this;
$.ajax({
url: navigator_item.url,
data: { authenticity_token: $('[name="csrf-token"]')[0].content},
method: 'DELETE',
success: function(res) {
...
}
});
I include jQuery into my application in another way
Instead of using:
plugins: [
new webpack.ProvidePlugin({...
You should add 'jquery': 'jquery/src/jquery' to aliases in the webpack config file:
module.exports = {
resolve: {
alias: {
'jquery': 'jquery/src/jquery'
}
}
It will provide module name 'jquery'. jQuery UI checks this name on init.
Then in you app.js file you write:
import $ from 'jquery'
import 'webpack-jquery-ui/css'
import 'webpack-jquery-ui/sortable' // if you need only sortable widget.
window.jQuery = $;
window.$ = $; // lazy fix if you want to use jQuery in your inline scripts.
The accepted answer doesn't work for me as the jQuery-ui package on NPM isn't pre-built and therefore doesn't contain jquery-ui.js; the package will either need built before use or all the widgets included/used individually.
Quickest way I got the whole package working was by first downloading the distributable version:
npm install jquery-ui-dist --save
I needed to add an alias for jquery-ui-dist to avoid a 'Cannot find module' error (using just require('jquery-ui-dist') won't work, because the .js filename is different), by adding this to webpack.config.js:
resolve: {
alias: {
'jquery-ui': 'jquery-ui-dist/jquery-ui.js'
}
},
Finally, you can use this in the .js file where the modules are loaded:
var jQuery = require('jquery');
require('jquery-ui');
Alternatively, you can avoid having to require the scripts when loading the modules, and having to declare jQuery as a variable, by using ProvidePlugin in your webpack.config.js:
plugins: [
new webpack.ProvidePlugin({
'jQuery': 'jquery',
'$': 'jquery',
'global.jQuery': 'jquery'
})
],
The steps that worked for me (in a Rails 5.1.6 project) aren't identical to any of the above:
Install jquery and jquery-ui: yarn add jquery and yarn add jquery-ui
Add the following to the webpack config (i.e. in /config/webpack/environment.js) to globally set $ and jquery and jQuery:
environment.plugins.prepend(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
jquery: 'jquery'
})
)
Require whichever individual jquery-ui package(s) you want, at the top of your pack (e.g at the top of /javascript/packs/application.js:
require("jquery-ui/ui/widgets/sortable")
Then you can call, for example, $('.selector').sortable() anywhere in your pack.
add jquery in your node_modules using;
npm install --save jquery jquery-ui
and add externals in your webpack.config.js like;
...
externals: {
// require("jquery") is external and available
// on the global var jQuery
"jquery": "jQuery",
"jquery-ui": "jquery-ui/jquery-ui.js",
}
it worked for me
You should import all of these and check which ones you really need.
require('jquery-ui/ui/core.js');
require('jquery-ui/ui/data.js');
require('jquery-ui/ui/form.js');
require('jquery-ui/ui/form-reset-mixin.js');
require('jquery-ui/ui/focusable.js');
require('jquery-ui/ui/disable-selection.js');
require('jquery-ui/ui/plugin.js');
require('jquery-ui/ui/labels.js');
require('jquery-ui/ui/position.js');
require('jquery-ui/ui/scroll-parent.js');
require('jquery-ui/ui/tabbable.js');
require('jquery-ui/ui/unique-id.js');
require('jquery-ui/ui/widget.js');
require('jquery-ui/ui/widgets/accordion.js');
require('jquery-ui/ui/widgets/autocomplete.js');
require('jquery-ui/ui/widgets/button.js');
require('jquery-ui/ui/widgets/checkboxradio.js');
require('jquery-ui/ui/widgets/controlgroup.js');
require('jquery-ui/ui/widgets/datepicker.js');
require('jquery-ui/ui/widgets/dialog.js');
require('jquery-ui/ui/widgets/draggable.js');
require('jquery-ui/ui/widgets/droppable.js');
require('jquery-ui/ui/widgets/menu.js');
require('jquery-ui/ui/widgets/mouse.js');
require('jquery-ui/ui/widgets/progressbar.js');
require('jquery-ui/ui/widgets/resizable.js');
require('jquery-ui/ui/widgets/selectable.js');
require('jquery-ui/ui/widgets/selectmenu.js');
require('jquery-ui/ui/widgets/slider.js');
require('jquery-ui/ui/widgets/sortable.js');
require('jquery-ui/ui/widgets/spinner.js');
require('jquery-ui/ui/widgets/tabs.js');
require('jquery-ui/ui/widgets/tooltip.js');
require('jquery-ui/ui/effect.js');
require('jquery-ui/ui/effects/effect-blind.js');
require('jquery-ui/ui/effects/effect-bounce.js');
require('jquery-ui/ui/effects/effect-clip.js');
require('jquery-ui/ui/effects/effect-drop.js');
require('jquery-ui/ui/effects/effect-explode.js');
require('jquery-ui/ui/effects/effect-fade.js');
require('jquery-ui/ui/effects/effect-fold.js');
require('jquery-ui/ui/effects/effect-highlight.js');
require('jquery-ui/ui/effects/effect-puff.js');
require('jquery-ui/ui/effects/effect-pulsate.js');
require('jquery-ui/ui/effects/effect-scale.js');
require('jquery-ui/ui/effects/effect-shake.js');
require('jquery-ui/ui/effects/effect-size.js');
require('jquery-ui/ui/effects/effect-slide.js');
require('jquery-ui/ui/effects/effect-transfer.js');
require('jquery-ui/ui/vendor/jquery-color/jquery.color.js');
I'm testing with the developer preview of Angular Version 2 and serving it up using pub serve
I would like to estalblish a convention to structure my files inside /lib/ as follows:
└── project/lib/root
├── root.css
├── root.dart
└── root.html
└── project/web/
├── index.html
└── index.dart
In my /web/index.dart file i am successfully able to initialize the #View and #Component from root.dart
However, when i preview in Dartium via pub serve - i can't seem to serve up /lib/root/root.html
#Component(
selector: 'jroot'
)
#View(
templateUrl: '../../lib/root/root.html',
directives: const [If]
)
class Root {
String content = 'Root - This is the entry point to the component';
List<Times> list;
Root(){
print('RootComponent Init');
}
}
Dartium Console:
GET http://localhost:8080/lib/root/root.html 404 (Not Found)
I've been reading the documents for polymer here which states:
"Non-Dart files under lib must use relative paths to import assets under lib:"
https://www.dartlang.org/polymer/app-directories.html
<!-- lib/a5/a6/a6.html imports lib/a4.html -->
<link rel="import" href="../../a4.html">
Running a python simple web server seems to work, so the problems is with pub serve:
python -m SimpleHTTPServer
Question: How do a configure pub serve to work with nested html files from the lib folder?
Ensure you have the proper entry points on your pubspec.yaml transformers:
name: 'project'
version: 0.0.1
dependencies:
angular2: '2.0.0-alpha.23'
browser: any
transformers:
- angular2:
entry_points:
- web/index.dart //this
reflection_entry_points:
- web/index.dart //this
Then I think this should work
templateUrl: 'packages/project/root/root.html',
or just
templateUrl: 'root.html',
I need read configuration from a external file properties in grails 3. In grails 2.x I link the file with:
grails.config.locations = ["classpath:config.properties"]
In the config.groovy, but this file do not exists in grails 3.
Have you any idea for solve?
Because Grails 3 is built on Spring Boot, you can use the Spring Boot mechanisms for externalized properties. Namely, using the spring.config.location command line parameter, or the SPRING_BOOT_LOCATION environment variable. Here's the Spring documentation page on it.
The example the documentation provides for the command line parameter is this:
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
The way I have been using it is by setting an environment variable, like this:
export SPRING_CONFIG_LOCATION="/home/user/application-name/application.yml"
One of the nice features is that you can leave some properties in the properties file that is bundled in the app, but if there are some properties you do not want to include (such as passwords), those can be set specifically in the external config file.
Take a look at https://gist.github.com/reduardo7/d14ea1cd09108425e0f5ecc8d3d7fca0
External configuration in Grails 3
Working on Grails 3 I realized that I no longer can specify external configuration using the standard grails.config.locations property in Config.groovy file.
Reason is obvious! There is no Config.groovy now in Grails 3. Instead we now use application.yml to configure the properties. However, you can't specify the external configuration using this file too!
What the hack?
Now Grails 3 uses Spring's property source concept. To enable external config file to work we need to do something extra now.
Suppose I want to override some properties in application.yml file with my external configuration file.
E.g., from this:
dataSource:
username: sa
password:
driverClassName: "org.h2.Driver"
To this:
dataSource:
username: root
password: mysql
driverClassName: "com.mysql.jdbc.Driver"
First I need to place this file in application's root. E.g., I've following structure of my Grails 3 application with external configuration file app-config.yml in place:
[human#machine tmp]$ tree -L 1 myapp
myapp
├── app-config.yml // <---- external configuration file!
├── build.gradle
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── grails-app
└── src
Now, to enable reading this file just add following:
To your build.gradle file
bootRun {
// local.config.location is just a random name. You can use yours.
jvmArgs = ['-Dlocal.config.location=app-config.yml']
}
To your Application.groovy file
package com.mycompany
import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean
import org.springframework.context.EnvironmentAware
import org.springframework.core.env.Environment
import org.springframework.core.env.PropertiesPropertySource
import org.springframework.core.io.FileSystemResource
import org.springframework.core.io.Resource
class Application extends GrailsAutoConfiguration implements EnvironmentAware {
public final static String LOCAL_CONFIG_LOCATION = "local.config.location"
static void main(String[] args) {
GrailsApp.run(Application, args)
}
#Override
void setEnvironment(Environment environment) {
String configPath = System.properties[LOCAL_CONFIG_LOCATION]
if (!configPath) {
throw new RuntimeException("Local configuration location variable is required: " + LOCAL_CONFIG_LOCATION)
}
File configFile = new File(configPath)
if (!configFile.exists()) {
throw new RuntimeException("Configuration file is required: " + configPath)
}
Resource resourceConfig = new FileSystemResource(configPath)
YamlPropertiesFactoryBean ypfb = new YamlPropertiesFactoryBean()
ypfb.setResources([resourceConfig] as Resource[])
ypfb.afterPropertiesSet()
Properties properties = ypfb.getObject()
environment.propertySources.addFirst(new PropertiesPropertySource(LOCAL_CONFIG_LOCATION, properties))
}
}
Notice that Application class implements EnvironmentAware Interface and overrides its setEnvironment(Environment environment):void method.
Now this is all what you need to re-enable external config file in Grails 3 application.
Code and guidance is taken from following links with little modification:
http://grails.1312388.n4.nabble.com/Grails-3-External-config-td4658823.html
https://groups.google.com/forum/#!topic/grails-dev-discuss/_5VtFz4SpDY
Source: https://gist.github.com/ManvendraSK/8b166b47514ca817d36e
I am having the same problem to read the properties file from external location in Grails 3. I found this plugin which helpme to read the properties from external location. It has feature to read .yml, .groovy files as well.
Follow the steps mentioned in the documentation and it will work.
The steps are like:
Add dependency in build.gradle:
dependencies {compile 'org.grails.plugins:external-config:1.2.2'}
Add this in application.yml grails:
config:
locations:
- file:///opt/abc/application.yml
Create file at external location. In my case /opt/abc/application.yml.
Build the application and run.
You can use
def cfg = new ConfigSlurper.parse(getClass().classLoader.getResource('path/myExternalConfigfile.groovy'))
When running from a .jar file, I found that Spring Boot looks at the current directory for an application.yml file.
java -jar app-0.3.jar
In the current directory, I created an application.yml file with one line:
org.xyz.app.title: 'XYZZY'
I also used this file to specify the database and other such info.
Seems like there is no externalised config out of the box: http://grails.1312388.n4.nabble.com/Grails-3-External-config-td4658823.html