ct-mapapps-gulp-js
v0.10.8
Published
A support lib for gulp based mapapps projects.
Downloads
1,187
Readme
ct-mapapps-gulp-js
A support lib for gulp based mapapps projects.
Features:
- .js transpile
- .ts transpile (experimental)
- .vue transpile (including experimental support for lang="ts")
- .less compile
- static error checking of js and vue files (linting)
- theme dependency support
- vuetify theme support
- css compression
- js compression
- API Documentation (jsdoc to Markdown and typedoc)
- Since version 0.1.x babel 7.x is used for JavaScript > transpilation!
- Since version 0.2.x gulp 4.x is used.
Installation
npm install ct-mapapps-gulp-js --save-dev
For Test execution
puppeteer
in version^13.0.0
is required to be a dependency in your project. For vue compilationvue-template-compiler
in a version matching yourvue
version is required to be a dependency in your project.
Usage
Scenario map.apps remote project with js transpilation only
Create a gulpfile.js
:
const gulp = require("gulp");
const mapapps = require("ct-mapapps-gulp-js");
mapapps.registerTasks({});
gulp.task("default", gulp.series("copy-resources", "js-lint", "js-transpile"));
Scenario map.apps remote project with themes and js transpilation
Create a gulpfile.js
:
const gulp = require("gulp");
const run_sequence = require("run-sequence");
const mapapps = require("ct-mapapps-gulp-js");
mapapps.registerTasks({
// a custom theme
themes: ["sample_theme"],
// custom theme is based on theme-everlasting
hasBaseThemes: true
});
gulp.task("default", gulp.series("copy-resources", "themes-copy", gulp.parallel("js-transpile", "themes-compile")));
Using the experimental typescript support
Typescript support is enabled for every .ts
source file in the project. All Typescript files
are transpiled using babel. No typechecks are performed by the transpilation or watch tasks.
In order to get IDE, linting and typechecking to work, create a tsconfig.json
file in your project's root directory:
npm install --save-dev typescript
npx tsc --init --declaration --target esnext --outdir lib --module amd
You may also want to configure the included/excluded source files in your tsconfig.json
, for example:
{
"compilerOptions": {
// ...
},
"include": ["./src/main/js/**/*"],
"exclude": ["./node_modules/**/*"]
}
In your package.json
, add two scripts for typechecking:
"scripts": {
"type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch",
}
Use npm run type-check
(run once) or npm run type-check:watch
(run in the background) to check for type errors. The "--noEmit" flag in the script definition is important: transpilation is done via gulp/babel.
Using typescript in .vue files
Use lang="ts"
in your script section:
<template>
<span>Hello World</span>
</template>
<script lang="ts">
// Typescript!
export default /* ... */;
</script>
To make imports of vue files work from typescript files, create a file in your source folder called vue-shims.d.ts
:
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
You must also make the vue typings available to the typescript compiler. TODO: We might distribute d.ts files for vue with mapapps in the future.
The following should work after the steps above:
import MyComponent from "./MyComponent.vue";
Creating type definitions
The create-types
task will auto-create typescript definition files (d.ts
) from existing code.
Types are generated from typescript files (ts
), but can be created from plain javascript files (js
) as well.
To generate types from javascript files, set the property allowJs
to true
in the tsconfig.json
.
The typescript compiler will try to make best guesses based on existing code and JSDocs.
To specify the output directory for the generated types, the property typingsDestLocation
is used.
To be able to publish the created types, a package.json
file for the resulting npm package has to be present at typingsTemplateLocation
.
If the version in the package.json
ends with -SNAPSHOT
then it will automatically replaced by a -next.<timestamp>
postfix to prepare publishing to npm.
This feature is experimental.
gulp create-types
Provided Tasks
clean
Deletes options.destLocation
watch
Watches for file changes and processes them
copy-resources
Copies all files in options.srcLocation
to options.destLocation
excluding options.copyIgnore
js-lint
Checks all .js files for typical errors. The goal is using es-lint.
The linting needs to be activated on watch, use options.lintOnWatch
flag to enable it.
See options.lintIgnore
and options.lintOptions
for the default settings.
js-transpile
Transpiles all .js
, .ts
, and .vue
files in options.srcLocation
to options.destLocation
.
If options.compress
is enabled then the files are compressed, too. TypeScript transpilation is experimental.
themes-copy
Copies themes to options.destLocation
with theme dependencies.
If options.hasBaseThemes
is true, then theme options.baseCommonThemeName
is copied to options.themesDestLocation
.
If options.themeChangeTargets
is configured, then defined themes are copied into the target themes.
If options.hasVuetify
is true, then vuetify resources are copied to all themes listed in options.themeChangeTargets
under key vuetify
.
If options.hasVuetify
is true, then a vuetify-mapping.json
is expected in the target themes. Which is used to rewrite the vuetify stylus configuration.
themes-compile
Compile *.less
and *.styl
files of the themes options.themes
.
themes-compress
Compress all <theme>/styles/styles.css
files.
This task is not supported in watch mode.
css-compress
Compress additional css files listed in options.compressCssFiles
array.
The listed files need to be relative to options.destLocation
.
The files will be modified in place.
This task is not supported in watch mode.
create-api-docs
Creates API.md files in bundles marked with a .apidoc
file.
The option createAPIDoc
must be enabled.
The .apidoc
file can be empty or contain JSON contents.
This sample shows the default values:
{
"include": ["**/*.js"],
"exclude": ["**/tests/**/*"]
}
create-types
Creates type definition files. This feature is experimental.
run-browser-tests
Starts a headless browser and loads test html pages which support test execution detection, e.g. the runner.html files of the intern.js test runner provided by map.apps.
For Test execution
puppeteer
in version^3.0.0
is required to be a dependency in your project.
You can preconfigure the urls to the test files by defining the option runBrowserTests
.
Or parametrize the task via command line:
gulp run-browser-tests --tests http://localhost:${jetty.server.port}/js/tests/test-base/runTests.html
Since 0.4.3 following syntax is supported as workaround for frontend-maven-plugin issue:
gulp run-browser-tests "--tests=http://a... http://b..."
rollup-build
Experimental rollup build process, replacing the js-transpile task. The rollup-build task will
search the entire "srcLocation" directory for bundles (detected by looking for manifest.json or package.json). Every bundle may have an build.config.js
configuration file, which will be loaded when the task runs.
Example content of build.config.js
:
module.exports = {
// Required, the chosen build type. Currently, only "bundle" is supported.
type: "bundle",
// List of public entry point modules. Only these files will be importable by other bundles, all other
// private module files within the current bundle will be bundled together and will *not* be exported.
//
// `entryPoints` can be a string (single entry point), an array of strings, or an object.
// The object syntax allows the user to name the entry points differently than the input files:
//
// Example:
// entryPoints: { "custom-name": "input-file.js" }
//
// Note that, by default, file extensions are stripped from entry points when using the string or array syntax. For example, the compilation of `bar.ts` below will result in a `bar.js` module, not in `bar.ts.js`.
// Extensions will not be stripped when using the object syntax.
entryPoints: ["foo.js", "bar.ts"]
// Optional, defaults to true. When this is true, all files within the "nls" folder will automatically
// be treated as entry points and will therefore be usable with the usual dojo nls system.
i18n: true,
// Optional, defaults to true. All files within the "tests" folder will automatically be treated as
// entry points.
tests: true,
// Optional, defaults to an empty array. Allows bundling of external modules from the `node_modules` folder.
//
// Example:
// // in your build.config.js
// npmDependencies: ["external-lib", "another-lib/nested/module"]
//
// // in a source file:
// import something from "external-lib"
// import somethingElse from "another-lib/nested/module";
//
// Note that the precise import path must be used; glob patterns are possible.
// The entire source code of the referenced node module and all its transitive dependencies will be included in the built bundle, so use this option with care.
npmDependencies: [],
// Optional expert configuration (know what you are doing!).
// Allows configuring the supported browser versions on a per-bundle basis.
// Currently only supported if babel is used to transpile source code.
// Entries here will override the defaults from the global configuration.
//targets: {
// firefox: 78,
// edge: 90,
// chrome: 90,
// safari: 13
//}
};
The build.config.js
may either export an object as displayed above or a Promise to such an object.
Note that ES6 module syntax is not currently supported within this file.
Special import syntax
rollup-build supports special import identifiers to access files or virtual modules that are not JavaScript modules. This can be used, for example, to embed the content of text files into the compiled JavaScript output:
import content from "text!./some-text-file.txt";
console.log(content); // Prints the text stored in the text file
Reference:
import foo from "text!./some-file";
Makes the file's content available as a string. The file should contain UTF-8 encoded text. The content will be included in the bundled output as JavaScript constant, so the input file does not need to be present in the compiled bundle.
import { configProperty } from "build-config!";
Imports the static configuration value
configProperty
into the current file. The value must be registered with therollupConfig
option (see below). Only plain old JavaScript data is supported (without cycles).Alternative syntax:
import configProperty from "build-config!configProperty";
import * as allConfigProperties from "build-config!";
import { sourceId } from "source-info!"
Will provide the source file id of the importing module, without its file extension. This value is not affected by bundling etc and will always reflect the state in the source directory.
Example:
my-bundle/my-directory/my-file.ts:
import { sourceId } from "source-info!"; console.debug(sourceId); // prints my-bundle/my-directory/my-file
Default options
{
// open for extensions
plugins: defaultPlugins.slice(0),
// enable debug output
debug: false,
// enable check for existing files during copy of resources
incremental: true,
// enable uglify during js-transpile task
compress: false,
// ignore files during js-compress task
compressIgnore: [],
// source directory
srcLocation: "./src/main/js",
// build output directory
destLocation: "./target/webapp/js",
// typings output directory
typingsDestLocation: "./target/typings",
// directory for package.json of typings project
typingsTemplateLocation: "./src/main/resources/typings",
// enables creation of API.md files in folders marked with .apidoc
createAPIDoc: false,
// list of urls to trigger js test execution
runBrowserTests: [],
// enable babel transpile for all .js and .vue files
// if disabled a .babelrc with empty object '{}' as body must be created to
// ensure that a bundle is transpiled.
forceTranspile: true,
// Defines how sourcemaps are created: "inline" | "file" | "none";
sourceMaps: "inline",
// path patterns which should be ignored by js-transpile goal
transpileIgnore: [],
// enables watch support of transpile task
// use it to disable watching of js-transpile, e.g. if pure rollup build is used
transpileEnableWatch: true,
// enable babel-runtime transformation(requires babel-runtime as available package
transpileUseBabelRuntime: false,
// enables the useBuiltIns flag during transformation
transpileUseBuiltIns: false,
// babel transpile targets: https://babeljs.io/docs/en/babel-preset-env#browserslist-integration
// eslint-disable-next-line max-len
// https://dev.azure.com/conterra/TeamProdEng/_wiki/wikis/Team-ct-Technologies-Product-Engineering.wiki/281/JavaScript-Compilation-Settings
transpileTargets: {
firefox: 78,
edge: 90,
chrome: 90,
safari: 13
},
// babel transpile settings
transpileOptions: function (): TranspileOptions {
const presets = [
[
"@babel/env",
{
targets: this.transpileTargets,
debug: this.debug,
modules: "amd",
useBuiltIns: this.transpileUseBuiltIns
}
],
["@babel/typescript"]
];
const plugins = [
[injectModulePlugin],
[importMetaAmd],
["@babel/plugin-syntax-dynamic-import"],
["@babel/plugin-syntax-import-meta"],
["@babel/proposal-class-properties"],
["@babel/proposal-object-rest-spread"],
["@babel/plugin-proposal-private-methods"],
["@babel/plugin-proposal-private-property-in-object"],
["@babel/plugin-proposal-numeric-separator"],
["@babel/plugin-transform-modules-amd", { strictMode: false }]
];
const useBabelRuntime = this.transpileUseBabelRuntime;
if (useBabelRuntime) {
const runtimeOptions =
typeof useBabelRuntime === "object"
? useBabelRuntime
: { helpers: true, polyfill: true, regenerator: true, moduleName: "babel-runtime" };
plugins.push(["@babel/transform-runtime", runtimeOptions]);
}
return {
presets: presets,
plugins: plugins,
assumptions: {
privateFieldsAsProperties: true
}
};
},
// which files should be ignored in tasks 'copy-resources'
copyIgnore: "**/*.{vue,ts,js}",
// which files should be ignored during linting by default
lintIgnore: " ",
// enables/disables linting on watch
lintOnWatch: false,
// if enabled first error will stop build process
lintFailFast: false,
// the default js lint options directly passed to gulp-eslint
lintOptions: {
envs: ["browser"],
parserOptions: {
"ecmaVersion": 2018,
"sourceType": "module"
},
baseConfig: {
extends: [
"eslint:recommended",
"plugin:vue/recommended"
]
},
rules: {},
globals: ["module"]
},
// source directory of theme bundles
themesSrcLocation: "./src/main/js/bundles",
// build output directory for theme bundles
themesDestLocation: "./target/webapp/js/bundles",
// enables 'styles/**' copy from source to destination during 'theme-copy' task
// this is not required if copy-resources task is used
copyThemeSources: false,
// names of custom theme bundles
themes: [],
// lookup from theme bundle names to target themes
// e.g.:
// themeChangeTargets: {
// "theme-everlasting": [
// "theme-summer",
// "theme-spring",
// "theme-winter",
// {
// name: "theme-liveconfiguration",
// filter: [
// "**/bundles/DataForm.less",
// "**/bundles/ToolButton.less",
// "**/bundles/Toolset.less",
// "**/dijit/**",
// "**/dojox/**",
// "**/images/**",
// "**/ui/**"
// ]
// }],
// // special key 'vuetify' to define copy targets for vuetify stylus sources
// "vuetify": ["theme-everlasting", "theme-summer", "theme-spring", "theme-winter"]
// }
themeChangeTargets: {},
// define that own themes are based on map.apps base themes
// this will trigger a copy of "theme-common" to target theme folder
// and the copy of "theme-everlasting" sources to the custom themes.
hasBaseThemes: false,
// define the name of the base theme, e.g. theme-everlasting
baseThemeName: "theme-everlasting",
// define the name of the common theme, e.g. theme-common
baseCommonThemeName: "theme-common",
// define the base themes source location
baseThemesLocation: "./target/unpacked/layout",
// defines that themes are dependent from vuetify
hasVuetify: false,
// Tests will not be included in the build if this is set to false.
// This is useful for release builds, when an optimized version of the bundle is desired.
rollupBuildTests: true,
// Static values that can be imported via `import { foo } from "build-config!"`;
// Values must be plain JavaScript values (not including functions) without cycles.
// Values used this way will be embedded into the built JavaScript.
// "build-config!" imports will not be present in the compiled output.
rollupConfig: {},
// Callback informed if watch processing is finished
watchFinishedReceiver: undefined
}
Developer Hints
Compile TypeScript -> JavaScript:
npm run build
Compiled javascript files are written into the dist
folder.
Use npm run watch
instead for continuous compilation in watch mode.
Run tests locally (requires built output):
npm run test
Debug tests locally:
npm run test-debug
Releasing:
The publish
command will automatically build the source code, so one can simply write:
npm publish