I am trying to use ember-index add on to generate index.jsp file instead of index.html. I have installed the ember-index addon and did the required changes as well.
My config/environment.js file looks like below
/* eslint-env node */
'use strict';
module.exports = function(environment) {
let ENV = {
modulePrefix: 'user-profile',
output: 'index.jsp',
environment,
rootURL: '/',
locationType: 'hash',
EmberENV: {
FEATURES: {
// Here you can enable experimental features on an ember canary build
// e.g. 'with-controller': true
},
EXTEND_PROTOTYPES: {
// Prevent Ember Data from overriding Date.parse.
Date: false
}
},
'ember-index': {
output: 'index.jsp',
content: {
file: 'example.txt',
includeInOutput: true,
includeInIndexHtml: false
}
},
APP: {
// Here you can pass flags/options to your application instance
// when it is created
}
};
return ENV;
};
Also my example.txt file looks like
<meta content="Example">
<h2>html to jsp</h2>
and finally in my index.html I have added below snippet
{{content-for 'ember-index'}}
But now when i am trying to build the ember project with ember build I am not able to see index.jsp file in my dist folder.
With a fresh app, this addon works as expected. Walk through the steps for the minimal example using a new Ember app, and you'll find what you missed.
Are you sure you're looking in the right place for the index.jsp? It is at dist/export/index.jsp after running ember build.
Did you forget to add the tag in your index.html? The readme specifies that for your files to be used, they must be specified like this:
<!-- app/index.html -->
<!DOCTYPE html>
<html>
<head>
...
{{content-for 'ember-index-1'}}
{{content-for 'ember-index-2'}}
</head>
<body>
...
</body>
</html>
Related
I use combination of Django+Vue, and I struggle to understand how do names that are created by vue-cli-service build or vue-cli-service serve are created and work, and how to set this in production.
If I do not have dynamic component imports, everything works smoothly.
My vue.config.js looks like that:
module.exports = {
pages: {
main: {
entry: "./src/main.js",
chunks: ["chunk-vendors"],
},
},
// Should be STATIC_URL + path/to/build
publicPath: "/front/",
// Output to a directory in STATICFILES_DIRS
outputDir: path.resolve(__dirname, "../_static/front/"),
// Django will hash file names, not webpack
filenameHashing: false,
productionSourceMap: false,
runtimeCompiler: true,
devServer: {
writeToDisk: true, // Write files to disk in dev mode, so Django can serve the assets
},
};
The result of built looks like that:
And I simply refer to these files in a Django template:
<div id="app"></div>
<script type="text/javascript" src="{% static 'front/js/chunk-vendors.js' %}"></script>
<script type="text/javascript" src="{% static 'front/js/main.js' %}"></script>
But as soon as I start using dynamic components, like that:
const User = () => import("./components/User")
Everything stops working, and in addition webpack creates some js files with hashed names in a static folder, and I can't figure out the logic (so I can't refer to them in the template.
Webpack has so called 'magic comments' - see here https://webpack.js.org/api/module-methods/#magic-comments
What you have there are not really dynamic routes, but lazy ones, which means their code is written into chunks rather than in the main js file and only loaded, when the component is loaded.
So to create a named chunk, you can write the import like that:
import(/* webpackChunkName: "about" */ "../views/About.vue")
However, you'll still have a hash value after that. This is done to avoid browser caching - the browser would not know that there is a new version of the file if it has the same name under certain conditions (like no etags set etc.) This is a webpack configuration that can be overwritten in the vue config. You can have a look for that here: https://github.com/vuejs/vue-cli/issues/1649
Edit: as I just saw you can even disable it with the filenamehashing config key: https://cli.vuejs.org/config/#filenamehashing
I'm working on Django-react project and having issue with rendering React component on Django server. To be precise, React always render me the same content even if I change it. I'm using Webpack, Babel-loader and running it on localhost.
project/templet/frontend/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Django-React</title>
</head>
<body>
<div id="app" class="columns"><!-- React --></div>
{% load static %}
<script type='text/javascript' src="{% static "frontend/main.js" %}"></script>
</body>
</html>
Entry point:
import ReactDOM from "react-dom";
import App from './components/App';
ReactDOM.render(<App/>, document.getElementById("app"));
Scripts in package.json:
"scripts": {
"dev": "webpack --mode development ./frontend/src/index.js --watch ./frontend/static/frontend/main.js",
"build": "webpack --mode production ./frontend/src/index.js --output ./frontend/static/frontend/main.js"
}
Babel config:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
So, when I write some content in App component (eg. render div with "test") I can see it in my browser, but when I want to change it, and after refresing page, get the same content from div tag
From what i can understand from your question, When you first render a div with 'test' in it, it renders, but after that, further changes dont update.
Its because the javascript is not being updated on Django and you need to use collectstatic to sync the builds which is not very efficient.
The way to go is to use django-webpack-loader and webpack-bundle-tracker.
install webpack-bundle-tracker
npm install --save-dev webpack-bundle-tracker
install django-webpack-loader:
pip install django-webpack-loader
django-webpack-loader is a python package which injects link and script tag for the bundles which webpack generates dynamically.
webpack-bundle-tracker plugin emits necessary information about webpack compilation process to a json file so django-webpack-loader can consume it.
For webpack to track changes made in your App, You need to create a server that monitors changes in your React app and bundle your JS.
Note: We make use of a node server.
// Webpack Server
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const config = require('./webpack.server.config');
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
inline: true,
historyApiFallback: true
}).listen(3000, '0.0.0.0', function (err, result) {
if (err) {
console.log(err)
}
console.log('Listening at 0.0.0.0:3000')
});
The config files used by webpack.server.js would be at webpack.server.config.js
// webpack.server.config.js
const path = require("path");
const BundleTracker = require('webpack-bundle-tracker');
module.exports = {
mode: 'development',
entry: {
main: './frontend/src/index.js',
devServer: 'webpack-dev-server/client?http://localhost:3000'
},
output: {
filename: "[name].js",
path: path.resolve('./frontend/static/frontend/bundles/'),
publicPath: 'http://localhost:3000/frontend/static/frontend/bundles/', // django-webpack-loader overrides django's STATIC_URL with this path
},
plugins: [
new BundleTracker({filename: './frontend/webpack-stats.json'}), // Pass the correct path to the WEBPACK_LOADER in django settings
],
devServer: {
contentBase: './frontend/static/frontend/bundles/',
},
};
Note that the server will by default keep the bundles in memory and
not write to disk
When the server is stopped, there would be no sign of the bundled files as they were not compiled to memory.
To build your files to memory in development, create another config file at webpack.dev.config.js
// webpack.dev.config.js
const path = require("path");
const BundleTracker = require('webpack-bundle-tracker');
module.exports = {
mode: 'development',
entry: {
main: './frontend/src/index.js',
},
output: {
filename: "[name].js",
path: path.resolve('./frontend/static/frontend/bundles/'),
},
plugins: [
new BundleTracker({filename: './frontend/webpack-stats.json'}), // Pass the correct path to the WEBPACK_LOADER in django settings
],
};
While to build your files for Production, create another config file at webpack.prod.config.js
// webpack.prod.config.js
const path = require("path");
const BundleTracker = require('webpack-bundle-tracker');
module.exports = {
mode: 'production',
entry: {
main: './frontend/src/index.js',
},
output: {
filename: "[name].js",
path: path.resolve('./frontend/static/frontend/dist/'),
},
plugins: [
new BundleTracker({filename: './frontend/webpack-stats-prod.json'}), // Pass the correct path to the WEBPACK_LOADER in django settings
],
};
In your Django settings;
import sys
import os
# Assuming this is your base directory
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Also assuming this is your base directory
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
# In development
WEBPACK_LOADER = {
'DEFAULT': {
'BUNDLE_DIR_NAME': 'bundles/',
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'), # Path to 'webpack-stats.json'
}
}
# In production
if not DEBUG:
WEBPACK_LOADER['DEFAULT'].update({
'BUNDLE_DIR_NAME': 'dist/',
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats-prod.json') # Path to 'webpack-stats-prod.json'
})
INSTALLED_APPS = (
...
'webpack_loader',
)
Your index.html should look like this now;
{% load render_bundle from webpack_loader %} <<< Add this.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Django-React</title>
</head>
<body>
<div id="app" class="columns">
<!-- React -->
</div>
{% render_bundle 'main' %} <<< Add this.
</body>
</html>
Now, Your package.json should look like this;
"scripts": {
"dev": "node ./webpack.server.js",
"build-dev": "webpack --mode development --config ./webpack.dev.config.js",
"build-prod": "webpack --mode production --config ./webpack.prod.config.js"
}
So, To develop with automatic bundling, just run:
npm run dev
To build your files to memory after the webpack server is stopped, just run:
npm run build-dev
And finally, to build with production optimizations, just run:
npm run build-prod
I tried to modify to your project, feel to adjust according to your project structure. Check the below referrences to guide you better. They helped me out!
References:
Let's modernize the way we handle frontend code with Django
Using Webpack transparently with Django + hot reloading React components as a bonus
Modern Django: Part 1: Setting up Django and React
The application runs fine in development, but once in production the generated webpack bundle file is serving the contents of index.html and not all the bundled modules and dependencies.
Whenever I check the bundle file on the server, everything seems alright, but the same path is served differently on the client.
webpack.config.js
//require our dependencies
var path = require('path')
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
module.exports = {
//the base directory (absolute path) for resolving the entry option
context: __dirname,
//the entry point we created earlier. Note that './' means
//your current directory. You don't have to specify the extension now,
//because you will specify extensions later in the `resolve` section
entry: [
'./assets/js/index'
],
output: {
path: path.resolve('./assets/bundles/'),
filename: "[name]-[hash].js"
},
plugins: [
//tells webpack where to store data about your bundles.
new webpack.NoErrorsPlugin(), // don't reload if there is an error
new BundleTracker({filename: './webpack-stats.json'}),
//makes jQuery available in every module
new webpack.ProvidePlugin({
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
],
module: {
loaders: [
// we pass the output from babel loader to react-hot loader
{
test: [/\.js$/, /\.es6$/, /\.jsx?$/],
exclude: /node_modules/,
loaders: ['babel'],
},
{ test: /\.css$/, loader: "style-loader!css-loader" }
]
},
resolve: {
//tells webpack where to look for modules
modulesDirectories: ['node_modules'],
//extensions that should be used to resolve modules
extensions: ['', '.js', '.jsx']
}
}
Served Content:
Uncaught SyntaxError: Unexpected token <
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!--<title></title>-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="/static/jquery/dist/jquery.js"></script>
<script type="text/javascript" src="/static/materialize-css/dist/js/materialize.min.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/javascript" src="/static/assets/bundles/main-210eb139915d8d6abedf.js" ></script>
</body>
Thanks in advance.
I can't get my jasmine unit-tests to load the a component for testing.
Webstorm is telling me that everything is good to go in terms of syntax. But when I load live-server to have the unit test load it doesn't seem to work.
I have it compiling to a test directory at root.
So here is my directory tree (abv for the ease):
-- client(src)
|-- common
|---- welcome.component.ts
|---- welcome.spec.ts
-- node_modules
-- tests(compiled spec and components)
|-- client(src)
|---- common
|------ welcome.component.ts
|------ welcome.spec.ts
--unit-tests.html
--systemjs.config.js
live server is giving me this:
GET /tests/client/common/welcome.component 404
welcome.spec.ts
/// <reference path="../../typings/main/ambient/jasmine/index.d.ts" />
import {WelcomeComponent} from './welcome.component';
describe('Welcome tests', () => {
let welcome:WelcomeComponent;
beforeEach(() => {
welcome = new WelcomeComponent('sir');
});
it('Nombre should equal sir', () => {
expect(welcome.nombre).toEqual('sir');
})
});
unit-tests.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Tests</title>
<link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
</head>
<body>
<!-- #1. add the system.js library -->
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
// #2. Configure systemjs to use the .js extension
// for imports from the app folder
System.config({
packages: {
'client': {defaultExtension: 'js'}
}
});
// #3. Import the spec file explicitly
System.import('tests/client/common/welcome.spec.js');
System.import('tests/client/common/header.spec.js')
// #4. wait for all imports to load ...
// then re-execute `window.onload` which
// triggers the Jasmine test-runner start
// or explain what went wrong.
.then(window.onload)
.catch(console.error.bind(console));
</script>
</body>
</html>
systemjs.config.js
(function(global) {
// map tells the System loader where to look for things
var map = {
'app': 'tests/client', // 'dist',
'rxjs': 'node_modules/rxjs',
'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
'#angular': 'node_modules/#angular'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' },
};
var packageNames = [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router',
'#angular/router-deprecated',
'#angular/testing',
'#angular/upgrade',
];
// add package entries for angular packages in the form '#angular/common': { main: 'index.js', defaultExtension: 'js' }
packageNames.forEach(function(pkgName) {
packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});
var config = {
map: map,
packages: packages
}
// filterSystemConfig - index.html's chance to modify config before we register it.
if (global.filterSystemConfig) { global.filterSystemConfig(config); }
System.config(config);
})(this);
I can add more if you need me too, the header.spec works great, but it's self-container. (expect true = true, etc)
SystemJS should be loading this for the unit-tests but it does not, the site itself works great so the Welcome.component is fine. But for some reason I cannot load the unit test.
Where would I be going wrong? I feel like this is a config issue, but I am not very familiar with unit-tests.
I had a similar issue the other day, take a look at this comment. If you have a spec-bundle.js or something similar, make sure var testing and var browser is referring to RC1 and not beta.
Also, if you have this somewhere: testing.setBaseTestProviders(
browser.TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
browser.TEST_BROWSER_STATIC_APPLICATION_PROVIDERS);
this is how it should look for RC1, it was different for beta
Basically, I'm quite experienced with Mocha (written thousands of unit tests), and I'm quite new to AngularJS (written just my first project).
Now I am wondering how I might unit test all the AngularJS stuff using Mocha.
I know that Mocha runs in the browser, and I have already done this. But how do I structure and setup things?
I guess I need to:
Load AngularJS
Load Mocha
Load my tests
Within each of the tests, I need to load a controller, a service, ... to test. How do I do that? I am not using require.js or something like that, the files are just script files with basically the following content:
angular.controller('fooController', [ '$scope', function ($scope) {
// ...
}]);
How do I reference and instantiate that controller within a test?
The same holds true for services, directives, ...
Do I need to create mocks for $scope, $http & co. for myself, or is there some help?
Please note that I am aware that there is the Karma test runner (formerly known as Testacular), but I do not want to switch my test runner completely.
One way of doing that is to use Angular $injector in your tests:
myModule_test.js
suite('myModule', function(){
setup(function(){
var app = angular.module('myModule', []);
var injector = angular.injector(['myModule', 'ng']);
var service = injector.get('myService');
});
suite('myService', function(){
test('should return correct value', function(){
// perform test with an instance of service here
});
});
});
your html should look similar to this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>myModule tests</title>
<link rel="stylesheet" media="all" href="vendor/mocha.css">
</head>
<body>
<div id="mocha"><p>Index</p></div>
<div id="messages"></div>
<div id="fixtures"></div>
<script src="vendor/mocha.js"></script>
<script src="vendor/chai.js"></script>
<script src="angular.min.js"></script>
<script src="myModule.js"></script>
<script>mocha.setup('tdd')</script>
<script src="myModule_test.js"></script>
<script>mocha.run();</script>
</body>
</html>
If you're creating an angular service that doesn't have any dependencies and isn't necessarily angular specific, you can write your module in an angular-agnostic way, then either write a separate small angular wrapper for it, or test for the presence of angular, and conditionally create a service for it.
Here's an example of an approach that I use to create modules that can be used both in angular, the browser, and node modules, including for mocha tests:
(function(global) {
//define your reusable component
var Cheeseburger = {};
if (typeof angular != 'undefined') {
angular.module('Cheeseburger', [])
.value('Cheeseburger', Cheeseburger);
}
//node module
else if (typeof module != 'undefined' && module.exports) {
module.exports = Cheeseburger
}
//perhaps you'd like to use this with a namespace in the browser
else if (global.YourAppNamespace) {
global.YourAppNamespace.Cheeseburger = Cheeseburger
}
//or maybe you just want it to be global
else {
global.Cheeseburger = Cheeseburger
}
})(this);