I am trying to implement the general example illustrated in:
https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/
where my directory structure does not match the "default".
/
index.html
js/
lib/
dojo/
dijit/
dojox/
my/
When I run against the development directories, everything works great! Using this config at runtime:
<script>
var dojoConfig = {
baseUrl: "/lib/_site/js/",
tlmSiblingsofDojo: false,
async: 1,
hasCache: {
// these are the values given above, not-built client code may test for these so they need to be available
"dojo-built": 1,
"dojo-loader": 1,
"dojo-undef-api": 0,
dom: 1,
"host-browser": 1,
// Disable deferred instrumentation by default in the built version.
"config-deferredInstrumentation": 0,
// Dojo loader has built-in "has" api. Since dojoConfig is used
// by Dojo loader, we can set the default here.
"dojo-has-api": 1,
// default
"config-selectorEngine": "lite",
"esri-featurelayer-webgl": 0,
"esri-promise-compatibility": 0,
"esri-promise-compatibility-deprecation-warnings": 1
},
packages: [
{
name: "dojo",
location: "lib/dojo"
},
{
name: "dijit",
location: "lib/dijit"
},
{
name: "dojox",
location: "lib/dojox"
},
{
name: "dstore",
location: "lib/dstore"
},
{
name: "dgrid",
location: "lib/dgrid"
},
{
name: "esri",
location: "lib/esri"
},
{
name: "moment",
location: "lib/moment",
main: "moment"
},
{
name: "my",
location: "my",
main: "app"
}
]
};
</script>
<script src="~/lib/_site/dist/js/lib/dojo/dojo.js"></script>
Dojo correctly locates "my" and the other "libs". But if I try to do an optimized custom build for production, everything works the same except the "my" directory is copied to the "lib" directory, but dojo is still looking for it where it should be?
The output directories look like:
/
index.html
js/
lib/
dojo/
dijit/
dojox/
my/
I am using this profile to build the optimized package..
*
* Based on the dojo-boilerplate
* https://github.com/csnover/dojo-boilerplate
* and https://github.com/tomwayson/esri-slurp-example
*
* Please refer to the Dojo Build tutorial for more details
* http://dojotoolkit.org/documentation/tutorials/1.10/build/
* Look to `util/build/buildControlDefault.js` for more information on available options and their default values.
*/
var profile = {
optimizeOptions: {
languageIn: "ECMASCRIPT6",
languageOut: "ECMASCRIPT5"
},
// `basePath` is relative to the directory containing this profile file; in this case, it is being set to the
// src/ directory, which is the same place as the `baseUrl` directory in the loader configuration.
basePath: "./js/",
tlmSiblings:false,
action: "release",
optimize: "closure", // requires Java 6 or later: http://code.google.com/p/closure-compiler/wiki/FAQ
layerOptimize: "closure",
useSourceMaps: false,
cssOptimize: "comments",
copyTests: false,
internStrings: true,
mini: true,
// The default selector engine is not included by default in a dojo.js build in order to make mobile builds
// smaller. We add it back here to avoid that extra HTTP request. There is also an "acme" selector available; if
// you use that, you will need to set the `selectorEngine` property in index.html, too.
selectorEngine: "lite",
// Strips all calls to console functions within the code. You can also set this to "warn" to strip everything
// but console.error, and any other truthy value to strip everything but console.warn and console.error.
// This defaults to "normal" (strip all but warn and error) if not provided.
stripConsole: "none",
// dojoBootText: "require.boot && require.apply(null, require.boot);",
insertAbsMids: 0,
// If present and truthy, instructs the loader to consume the cache of layer member modules
noref: true,
// A list of packages that will be built. The same packages defined in the loader should be defined here in the
// build profile.
packages: [
// "app" is a sample path for your application
// set this accordingly
{
name: "my",
location: "my"
},
{
name: "dojo",
location: "lib/dojo"
},
{
name: "dijit",
location: "lib/dijit"
},
{
name: "dojox",
location: "lib/dojox"
},
{
name: "dstore",
location: "lib/dstore"
},
{
name: "dgrid",
location: "lib/dgrid"
},
{
name: "esri",
location: "lib/esri"
},
{
name: "moment",
location: "lib/moment",
main: "moment",
trees: [
// don"t bother with .hidden, tests, min, src, and templates
[".", ".", /(\/\.)|(~$)|(test|txt|src|min|templates)/]
],
resourceTags: {
amd: function (filename, mid) {
return /\.js$/.test(filename);
}
}
}
],
// Any module in an application can be converted into a "layer" module, which consists of the original module +
// additional dependencies built into the same file. Using layers allows applications to reduce the number of HTTP
// requests by combining all JavaScript into a single file.
layers: {
// This is the main loader module. It is a little special because it is treated like an AMD module even though
// it is actually just plain JavaScript. There is some extra magic in the build system specifically for this
// module ID.
"dojo/dojo": {
// By default, the build system will try to include `dojo/main` in the built `dojo/dojo` layer, which adds
// a bunch of stuff we do not want or need. We want the initial script load to be as small and quick to
// load as possible, so we configure it as a custom, bootable base.
boot: true,
customBase: true,
include: [
"dojo/domReady",
/** enforce some modules loading */
/** not included because dom is -1 */
"dojo/_base/browser",
"esri/core/request/script",
// esri stuff for 3D maps
"esri/portal/support/layersCreator",
"esri/views/3d/layers/VectorTileLayerView3D"
]
// You can define the locale for your application if you like
// includeLocales: ["en-us"]
},
"esri/identity/IdentityManager": {
include: [
"esri/identity/IdentityManager"
]
},
"esri/views/MapView": {
include: [
"esri/views/MapView",
"esri/views/2d/layers/GraphicsLayerView2D",
"esri/views/2d/layers/FeatureLayerView2D",
"esri/views/2d/layers/TiledLayerView2D"
],
exclude: [
"esri/widgets/support/widget"
]
},
"esri/views/SceneView": {
include: [
"esri/views/SceneView",
"esri/layers/graphics/controllers/I3SOnDemandController",
"esri/layers/SceneLayer",
"esri/views/3d/layers/ElevationLayerView3D",
"esri/views/3d/layers/FeatureLayerView3D",
"esri/views/3d/layers/SceneLayerView3D",
"esri/views/3d/layers/TiledLayerView3D"
],
exclude: [
"esri/widgets/support/widget"
]
},
"esri/WebMap": {
include: [
"esri/WebMap"
]
},
"esri/WebScene": {
include: [
"esri/WebScene"
]
},
"esri/layers/VectorTileLayer": {
include: [
"esri/layers/VectorTileLayer"
]
},
"esri/views/2d/layers/VectorTileLayerView2D": {
include: [
"esri/views/2d/layers/VectorTileLayerView2D"
],
exclude: ["esri/views/MapView"]
},
"esri/views/2d/layers/support/FeatureLayerView2DWebGL": {
include: [
"esri/views/2d/layers/support/FeatureLayerView2DWebGL"
],
exclude: ["esri/views/MapView"]
},
"esri/core/workers/WorkerConnection": {
include: [
"esri/core/workers/WorkerConnection"
]
},
"esri/views/vectorTiles/WorkerTileHandler": {
include: [
"esri/views/vectorTiles/WorkerTileHandler"
]
},
"esri/widgets/support/widget": {
include: [
"esri/widgets/support/widget"
]
}
}
I just can't figure out why! I have tried 10thteen variations. I have not tried to copy the "my" directory back to its proper location, as I shouldn't have to!! If I can't figure it out and manual copying does work, I will just add a copy after the dojo build in the process. BTW-Using NPM and grunt.
Any ideas? Your time and expertise are greatly appreciated!!
Cheers!
BTW-Using NPM and grunt.
EDIT: Here is the grunt stuff used to run the custom build.
A quick note on the custom build. I was trying to "bake" a default
profile into the build by defining a "defaultConfig in the build
profile, as it didn't seem to be working. So I hardwired the
dojoConfig as illustrated above. See the Application Build Profile
section of:
https://dojotoolkit.org/documentation/tutorials/1.10/build/index.html
So the contents of my grunt file that matter:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: {
options: {
force: true
},
any: {
src: ''
}
},
dojo: {
dist: {
options: {
releaseDir: '../dist/js/lib',
}
},
options: {
profile: 'site.profile.js',
dojo: './js/lib/dojo/dojo.js',
load: 'build',
cwd: './',
basePath: './js/'
}
}
});
require('load-grunt-tasks')(grunt, { scope: 'devDependencies' });
require('time-grunt')(grunt);
grunt.registerTask('none', function () { });
grunt.registerTask('default', 'dist');
grunt.registerTask('my-dojo', function () {
grunt.config('clean.any.src', ['./dist/js/lib']);
grunt.task.run('clean:any');
grunt.task.run('dojo');
grunt.config('clean.any.src', ['./dist/js/lib/**/*.uncompressed.js']);
grunt.task.run('clean:any');
});
};
As mentioned it copies everything to the releaseDir, including "my", where it should end up in ./dist/js.
Related
as a recruitment task I have to copy layout using HTML/CSS and Vanilla JS. I've got a starter pack as a webpack bundle and according to recruiter documentation i have to just install all dependencies using npm install. After creating some layout in css i had to use img tag and here my problem start. First I had error that I'm missing img-loader, so I installed it. Now i can't see image but only alt attribute text.
this is my webpack.config.js for file-loader and img-loader:
{
test: /\.(jp?g|png|gif|svg)$/i,
use: [
{
loader: "file-loader",
options: {
name: "img/[name].[ext]",
},
},
{
loader: "img-loader",
options: {
enabled: isProduction,
gifscale: {
interlaced: false,
},
mozjpeg: {
progressive: true,
arithmetic: false,
},
optipng: false,
pngquant: {
floyd: 0.5,
speed: 2,
},
svgo: {
plugins: [{ removeTitle: true }, { covertPathData: false }],
},
},
},
],
},
here is file structure: file structure
I tried installing all dependencies step by step, changing config and I searched internet across. Unfortunately i couldn't find any solution.
I'm using svgo-loader to optimize the svg images and its using the default configuration for this. I want to add some custom configuration like I dont want to remove the viewBox from svg as it makes defining the dimensions of svg really hard.
I found the following solutions from internet... but none of them are working, and I always get the viewBox removed from svg.
{
loader: 'svgo-loader',
options: {
plugins: [{
removeViewBox: false
}]
}
}
{
loader: 'svgo-loader',
options: {
externalConfig: "svgo-config.yml"
}
}
{
loader: 'svgo-loader',
options: {
configFile: './svgo.config.js'
}
}
Content of config.yml file
plugins:
- removeTitle: false
- remoViewBox: false
Content of svgo.config.js
const { extendDefaultPlugins } = require('svgo');
module.exports = {
plugins: extendDefaultPlugins([
{
name: 'removeTitle',
active: false
},
{
name: 'removeViewBox',
active: false
},
])
};
For the configFile solution, I feel like it's just not picking the given file, because if I will provide the wrong file location (or some file location that doesnt exists) it works exactly same as the default case (my expectation was to have an error smething like ...wrong file supplied).
Using svgo-loader v3.0.0 (with svgo v2.4.0 or newer):
create svgo.config.js in root project folder with following content:
module.exports = {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
removeViewBox: false,
},
},
},
],
};
in webpack.config.js
{
test: /\.svg$/i,
use: [
{
loader: 'file-loader',
},
{
loader: 'svgo-loader',
},
]
},
There is no need to pass any options for the svgo-loader in the webpack config. Just passing the default config under the root directory with the required options for fine-tuning the loader worked for me.
Make sure its named svgo.config.js as this is this file that will be picked by the svgo for loading in options...much like how we pass config files for other things like prettier, ts, and so on.
webpack.config.js
{
test: /\.svg$/i,
use: [
{
loader: 'file-loader',
},
{
loader: 'svgo-loader',
},
]
},
And this is my svgo.config.js, since I just need to preserve the viewBox attribute on my SVG I have added that...you can use this complete list for your reference.
const { extendDefaultPlugins } = require('svgo');
module.exports = {
plugins: extendDefaultPlugins([
{
name: 'removeViewBox',
active: false
},
])
};
Thanks for the help #trySound!
I have just tried to install a second theme onto my present gatsby install, following the steps outlined within the Multiple Themes tutorial. I am having some trouble with the linking of resources for the new theme. Because it lives within node_modules, I would guess that this is where it should be referencing. At present, it seems to be trying to reference the main src directory for the first theme.
Not sure what exactly I am doing wrong here. Here is a copy of my gatsby-config for reference, specifically the plugins section:
plugins: [
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `gatsby-mytheme-tailwind`,
short_name: `mytheme-main`,
start_url: `/`,
background_color: fullConfig.theme.colors.white,
theme_color: fullConfig.theme.colors.blue["400"],
display: `minimal-ui`,
icon: `src/images/MyTheme-Icon.png`,
},
},
//Custom Themes
{
resolve: `gatsby-tailwind-simplicity-theme`,
options: {
basePath: `/simplicity-itself`,
},
},
//Rest of the plugins
`gatsby-plugin-eslint`,
`gatsby-plugin-react-helmet`,
`gatsby-plugin-root-import`,
{
resolve: `gatsby-plugin-postcss`,
options: {
postCssPlugins: [
require(`tailwindcss`)(tailwindConfig),
require(`autoprefixer`),
...(process.env.NODE_ENV === `production`
? [require(`cssnano`)]
: []),
],
},
},
`gatsby-plugin-offline`,
]
Even after adding favicon to gatsby hello world starter project in gatsby config file, its not working.
I tried googling and searched in stackoverflow for similar question, How do i add favicon gatsby-config.js?. But that doesn't help or i maybe wrong somewhere.
Please correct me!!
GATSBY CONFIG.JS
/**
* Configure your Gatsby site with this file.
*
* See: https://www.gatsbyjs.org/docs/gatsby-config/
*/
module.exports = {
/* Your site config here */
siteMetadata: {
title: "xxxxxxx",
author: "Subin",
},
plugins: [
"gatsby-plugin-react-helmet",
{
resolve: "gatsby-source-contentful",
options: {
spaceId: process.env.CONTENTFUL_SPACE_ID,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
},
},
"gatsby-plugin-sass",
// this plugin will pull all the files in our project system
{
resolve: "gatsby-source-filesystem",
options: {
name: "src",
path: `${__dirname}/src/`,
icon: `../src/images/favicon-32x32.png`,
},
},
"gatsby-plugin-sharp",
// REMARK plugin needed to extract the markdown files and parses
{
resolve: "gatsby-transformer-remark",
options: {
plugins: [
"gatsby-remark-relative-images",
{
resolve: "gatsby-remark-images",
options: {
maxWidth: 750,
linkImagesOriginal: false,
},
},
],
},
},
],
}
PROJECT DIRECTORY IMAGE
Image : Tree hierarchy of my project structure
To display your favicon, you need to have the gatsby-plugin-manifest installed, it doesn't come with the hello world starter.
npm install --save gatsby-plugin-manifest
And here is your gatsby-config.js with some default settings to this plugin:
/**
* Configure your Gatsby site with this file.
*
* See: https://www.gatsbyjs.org/docs/gatsby-config/
*/
module.exports = {
/* Your site config here */
siteMetadata: {
title: "xxxxxxx",
author: "Subin"
},
plugins: [
"gatsby-plugin-react-helmet",
{
resolve: "gatsby-source-contentful",
options: {
spaceId: process.env.CONTENTFUL_SPACE_ID,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN
}
},
"gatsby-plugin-sass",
// this plugin will pull all the files in our project system
{
resolve: "gatsby-source-filesystem",
options: {
name: "src",
path: `${__dirname}/src/`,
icon: `../src/images/favicon-32x32.png`
}
},
"gatsby-plugin-sharp",
// REMARK plugin needed to extract the markdown files and parses
{
resolve: "gatsby-transformer-remark",
options: {
plugins: [
"gatsby-remark-relative-images",
{
resolve: "gatsby-remark-images",
options: {
maxWidth: 750,
linkImagesOriginal: false
}
}
]
}
},
{
resolve: `gatsby-plugin-manifest`,
options: {
name: "xxx",
short_name: "xxxx",
start_url: "/",
background_color: "#6b37bf",
theme_color: "#6b37bf",
// Enables "Add to Homescreen" prompt and disables browser UI (including back button)
// see https://developers.google.com/web/fundamentals/web-app-manifest/#display
display: "standalone",
icon: "src/images/favicon-32x32.png" // This path is relative to the root of the site.
}
}
]
};
Remember to stop your development server and start a brand new one when modifying gatsby-config.js in order to see your changes.
Can you try this and let me know if it works as intended?
I come from a Java/Maven background where you would create WAR files to deploy. Maven provides the ability to "filter" files during the build and replace variables at build time with targeted information for the environment you're deploying to.
Now I am working in Node.js and I was wondering if there's a similar facility and best practice you can use in Node.js whereby I could minify my javascript into a single file but at the same time filter variables respective to the environment I'm deploying to.
For instance, there's an app_name config that I'd like to be environment specific:
exports.config = {
app_name : ['$APPNAME-$ENV'],
license_key : 'xxx',
logging : {
level : '$DEBUG_LEVEL'
}
};
So I'd like to be able to update all the $ variables above with environment specific variables into a separate minified JS file. It seems like I'd have to copy the files into a staging area, do a string replace on the variables and then minify. Does that seem reasonable or are there any recommendations on how to best accomplish this in the Node world?
Here's what I ended up doing with GruntJS to accomplish what was talked about above (clean, copy, string-replace, JSHint, and Google CC to minify). I posted a more complete reading of this here for those interested in a deeper dive.
(function () {
'use strict';
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: ["dist"],
copy: {
build: {
files: [
{src: ['./**/*.js', './*.json', './stackato.yml', './README.md', './nunit.js', './test/**/*', '!./dist/**/*', '!./node_modules/**/*', '!./Gruntfile.js'], dest: 'dist/'}
]
}
},
'string-replace': {
dev: {
files: {
"dist/": ["newrelic.js", "stackato.yml", "package.json"]
},
options: {
replacements: [
{
pattern: '$APPNAME',
replacement: "services-people"
},
{
pattern: '$VERSION',
replacement: "1.0.6"
},
{
pattern: 'server.js',
replacement: "server.min.js"
},
{
pattern: '$ENV',
replacement: "DEV"
},
{
pattern: '$PDS_PWD',
replacement: ""
},
{
pattern: '$INSTANCES',
replacement: "1"
},
{
pattern: '$NEWRELIC_TRACE_LVL',
replacement: "trace"
}
]
}
},
prod: {
files: {
"dist/": ["newrelic.js", "stackato.yml", "package.json"]
},
options: {
replacements: [
{
pattern: '$APPNAME',
replacement: "services-people"
},
{
pattern: '$VERSION',
replacement: "1.0.6"
},
{
pattern: 'server.js',
replacement: "server.min.js"
},
{
pattern: '$ENV',
replacement: "prod"
},
{
pattern: '$PDS_PWD',
replacement: ""
},
{
pattern: '$INSTANCES',
replacement: "2"
},
{
pattern: '$NEWRELIC_TRACE_LVL',
replacement: "info"
}
]
}
}
},
jshint: {
options: {
curly: true,
eqeqeq: true,
eqnull: true,
strict: true,
globals: {
jQuery: true
},
ignores: ['dist/test/**/*.js']
},
files: ['Gruntfile.js', 'dist/**/*.js']
},
nodeunit: {
all: ['dist/test/*-tests.js']
},
'closure-compiler': {
build: {
closurePath: '.',
js: 'dist/**/*.js',
jsOutputFile: 'dist/server.min.js',
maxBuffer: 500,
options: {
compilation_level: 'ADVANCED_OPTIMIZATIONS',
language_in: 'ECMASCRIPT5_STRICT',
debug: false
// formatting: 'PRETTY_PRINT'
}
}
}
});
grunt.loadNpmTasks('grunt-closure-compiler');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-nodeunit');
grunt.loadNpmTasks('grunt-string-replace');
// Default task(s).
grunt.registerTask('default', ['clean', 'copy:build', 'string-replace:dev', 'jshint', 'closure-compiler:build']);
grunt.registerTask('prod', ['clean', 'copy:build', 'string-replace:prod', 'jshint', 'closure-compiler:build']);
};
})();
On the CLI, you can just use "grunt" to spin up the DEV version or "grunt prod" to build the PROD version.