Add Webpack config for package publishing (Fixes #746) (#754)

This commit is contained in:
Alex Gibson 2021-12-14 23:26:49 +00:00 коммит произвёл GitHub
Родитель a92538c7d5
Коммит f5f912a24f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
24 изменённых файлов: 4105 добавлений и 230 удалений

Просмотреть файл

@ -1,3 +1,74 @@
module.exports = {
extends: "@mozilla-protocol/eslint-config",
env: {
'node': true,
'commonjs': true,
'jasmine': true,
'es2017': true
},
extends: [
'eslint:recommended'
],
rules: {
// Require `let` or `const` instead of `var`
// https://eslint.org/docs/rules/no-var
'no-var': 'error',
// Require `const` declarations for variables that are never reassigned after declared
// https://eslint.org/docs/rules/prefer-const
'prefer-const': 'error',
// This option sets a specific tab width for your code
// https://eslint.org/docs/rules/indent
'indent': ['error', 4],
// Disallow mixed 'LF' and 'CRLF' as linebreaks
// https://eslint.org/docs/rules/linebreak-style
'linebreak-style': ['error', 'unix'],
// Specify whether double or single quotes should be used
'quotes': ['error', 'single'],
// Require or disallow use of semicolons instead of ASI
'semi': ['error', 'always'],
// Enforce location of semicolons
// https://eslint.org/docs/rules/semi-style
'semi-style': ['error', 'last'],
// Require camel case names
// https://eslint.org/docs/rules/camelcase
'camelcase': ['error', { 'properties': 'always' }],
// Use type-safe equality operators
// https://eslint.org/docs/rules/eqeqeq
'eqeqeq': ['error', 'always'],
// Require newlines around variable declarations
// https://eslint.org/docs/rules/one-var-declaration-per-line
'one-var-declaration-per-line': ['error', 'always'],
// Require constructor names to begin with a capital letter
// https://eslint.org/docs/rules/new-cap
'new-cap': 'error',
// Disallow Use of alert, confirm, prompt
// https://eslint.org/docs/rules/no-alert
'no-alert': 'error',
// Disallow eval()
// https://eslint.org/docs/rules/no-eval
'no-eval': 'error',
// Disallow empty functions
// https://eslint.org/docs/rules/no-empty-function
'no-empty-function': 'error',
// Require radix parameter
// https://eslint.org/docs/rules/radix
'radix': 'error',
// Disallow the use of `console`
// https://eslint.org/docs/rules/no-console
'no-console': 'error'
}
};

1
.github/workflows/node.js.yml поставляемый
Просмотреть файл

@ -29,5 +29,4 @@ jobs:
sudo apt install libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1920x1200x24 -ac +extension GLX
- run: npm ci
- run: npm run build --if-present
- run: npm test

1
.gitignore поставляемый
Просмотреть файл

@ -1,5 +1,6 @@
node_modules
dist
package
src/data/colors.json
src/data/index.json
src/data/icons.json

Просмотреть файл

@ -1,5 +1,11 @@
# HEAD
## Features
* **node:** Create a standalone Webpack config for compiling the Protocol NPM package (#746).
* **js:** Update protocol to extend standard ESLint configs (#753)
* **js:** Move Karma test command to NPM script (#748).
## Bug Fixes
* **js:** use more robust polyfill for `e.matches` (#736)
@ -8,7 +14,6 @@
## Features
* **js:** Move Karma test command to NPM script (#748).
* **linting:** Updated ESLint and Stylelint, moved to NPM scripts (#745).
* **node:** Bumped Node.js to v16 (#745).

Просмотреть файл

@ -13,6 +13,7 @@
[releases]: https://github.com/mozilla/protocol/releases/latest
[readme]: https://github.com/mozilla/protocol/blob/master/src/assets/package/README.md
[changelog]: https://github.com/mozilla/protocol/blob/master/CHANGELOG.md
[webpack]: https://webpack.js.org/
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
@ -484,19 +485,29 @@ dist/assets
│   └── protocol-sidemenu.js
```
# Build Process
# Building the docs
The build sequence consists of a small set of [Gulp][gulp] tasks. While you'll probably only need `gulp` and `gulp --dev` most of the time, the other tasks can be called independently to process only a subset of your source files:
The build sequence for the docs consists of a small set of [Gulp][gulp] tasks. While you'll probably only need `gulp` and `gulp --dev` most of the time, the other tasks can be called independently to process only a subset of your source files:
| Task | Description
| --- | ---
| `gulp` | Build everything and start the development server.
| `gulp` | Build the docs and start the development server.
| `gulp --dev` | Do everything `gulp` does, but with file watching.
| `gulp build` | Just build everything.
| `gulp build` | Just build the docs.
# Building the NPM package
We use a Webpack[webpack] configuration for building the contents of the NPM package ready for publishing. To build the package, run:
```
npm run build
```
This will install dependencies, lint CSS/JS files, and then build the package content in the `./package/` directory.
# Running tests
To start the build process and then run front-end JS tests against the processed files:
To perform the package build process above and then run front-end JS tests against the processed files:
```
npm test
@ -512,8 +523,8 @@ Protocol is published to NPM under the `@mozilla-protocol/core` namespace/packag
4. Run `npm install` to update the package-lock.json file.
5. Submit a pull request with your changes (or commit directly to `master` if you have permission). Once the changes have been merged to master:
6. Tag a new release. You can do this either using [Git tag][git-tag], or directly on the [GitHub website][releases].
7. Run `npm test` to run the build script and front-end tests. The package contents will be located in `./dist/assets/protocol/`.
8. If the build is successful and all tests pass, publish to NPM using `npm publish ./dist/assets/protocol/`.
7. Run `npm test` to run the build script and front-end tests. The package contents will be located in `./package/`.
8. If the build is successful and all tests pass, publish to NPM using `npm publish ./package/`.
# Deployment

Просмотреть файл

@ -1,5 +0,0 @@
'use strict';
module.exports = {
extends: '@mozilla-protocol/eslint-config/index-node',
};

Просмотреть файл

@ -8,52 +8,6 @@ module.exports = {
clean: {
dest: './dist/'
},
compressCss: {
tasks: {
protocol: {
src: [
`${dest}/protocol/protocol/css/*.css`,
`!${dest}/protocol/protocol/css/*.min.css`
],
dest: `${dest}/protocol/protocol/css/`,
},
docs: {
src: [
`${dest}/docs/css/*.css`,
`!${dest}/docs/css/*.min.css`
],
dest: `${dest}/docs/css/`,
}
},
rename: {
suffix: '.min'
}
},
compressJS: {
tasks: {
protocol: {
src: [
`${dest}/protocol/protocol/js/**/*.js`,
`!${dest}/protocol/protocol/js/*.min.js`
],
dest: `${dest}/protocol/protocol/js/`,
},
docs: {
src: [
`${dest}/docs/js/**/*.js`,
`${dest}/docs/js/*.min.js`,
],
dest: `${dest}/docs/js/`,
}
},
rename: {
suffix: '.min'
},
settings: {
errLogToConsole: true,
sourceComments: true
}
},
concatJS: {
docs: {
src: [
@ -79,20 +33,12 @@ module.exports = {
}
},
sassCopy: {
protocol: {
src: `${src}/sass/protocol/**/*.scss`,
dest: `${dest}/protocol/protocol/css/`
},
docs: {
src: [
`${src}/sass/docs/**/*.scss`,
`${src}/sass/demos/**/*.scss`
],
dest: `${dest}/docs/css/`
},
includes: {
src: `./node_modules/@mozilla-protocol/**/*.scss`,
dest: `${dest}/protocol/protocol/css/includes/`
}
},
jsCopy: {
@ -113,14 +59,10 @@ module.exports = {
dest: './src/data/icons.json'
},
staticCopy: {
package: {
src: `${src}/package/*`,
dest: `${dest}/protocol`
},
img: {
src: [
`${src}/img/**/*`,
`./node_modules/@mozilla-protocol/assets/**/*`
'./node_modules/@mozilla-protocol/assets/**/*'
],
dest: `${dest}/protocol/protocol/img/`
},
@ -133,12 +75,12 @@ module.exports = {
dest: './dist/static'
},
colorData: {
src: `./node_modules/@mozilla-protocol/tokens/dist/colors/colors.json`,
dest: `./src/data`
src: './node_modules/@mozilla-protocol/tokens/dist/colors/colors.json',
dest: './src/data'
},
tokenData: {
src: `./node_modules/@mozilla-protocol/tokens/dist/index.json`,
dest: `./src/data`
src: './node_modules/@mozilla-protocol/tokens/dist/index.json',
dest: './src/data'
}
},
serve: {
@ -155,10 +97,7 @@ module.exports = {
},
watch: {
watchers: {
static: [
'./src/static/**/*',
`${src}/package/*`
],
static: ['./src/static/**/*'],
js: [`${src}/js/**/*.js`],
css: `${src}/sass/**/*.scss`,
drizzle: [

Просмотреть файл

@ -8,8 +8,6 @@ const compileSass = require('./compile-sass');
const copySass = require('./copy-sass');
const copyJS = require('./copy-js');
const concatJS = require('./concat-js');
const compressCSS = require('./compress-css');
const compressJS = require('./compress-js');
const generateIconData = require('./generate-icon-data');
/*
@ -29,8 +27,7 @@ const build = gulp.series(
generateIconData,
copyStaticFiles,
drizzleTask,
gulp.parallel(compileSass, copySass, copyJS, concatJS),
gulp.parallel(compressCSS, compressJS)
gulp.parallel(compileSass, copySass, copyJS, concatJS)
);
// Register build task (for continuous deployment via Netlify)

Просмотреть файл

@ -10,10 +10,10 @@ const merge = require('merge-stream');
// Compile the main Protocol Sass file(s) to CSS.
function compileSass() {
let tasks = [];
const tasks = [];
Object.keys(config).forEach((key) => {
let val = config[key];
const val = config[key];
tasks.push(gulp.src(val.src)
.pipe(plumber({ errorHandler: handleErrors }))
.pipe(sourcemaps.init())

Просмотреть файл

@ -8,10 +8,10 @@ const merge = require('merge-stream');
// Create minified versions of all CSS assets.
function compressCSS() {
let tasks = [];
const tasks = [];
Object.keys(config.tasks).forEach((key) => {
let val = config.tasks[key];
const val = config.tasks[key];
tasks.push(gulp.src(val.src)
.pipe(cleanCSS({processImport: false}))
.pipe(rename(config.rename))

Просмотреть файл

@ -10,10 +10,10 @@ const merge = require('merge-stream');
// Create minified versions of all JS assets.
function compressJS() {
let tasks = [];
const tasks = [];
Object.keys(config.tasks).forEach((key) => {
let val = config.tasks[key];
const val = config.tasks[key];
tasks.push(gulp.src(val.src)
.pipe(plumber({ errorHandler: handleErrors }))
.pipe(uglify())

Просмотреть файл

@ -9,10 +9,10 @@ const merge = require('merge-stream');
// Concatenate docs JS files.
function concatJS() {
let tasks = [];
const tasks = [];
Object.keys(config).forEach((key) => {
let val = config[key];
const val = config[key];
tasks.push(gulp.src(val.src)
.pipe(plumber({ errorHandler: handleErrors }))
.pipe(concat(key + '.js'))

Просмотреть файл

@ -6,9 +6,9 @@ const merge = require('merge-stream');
// Copy across all original JS files for distribution.
function copyJS() {
let tasks = [];
const tasks = [];
Object.keys(config).forEach((key) => {
let val = config[key];
const val = config[key];
tasks.push(gulp.src(val.src).pipe(gulp.dest(val.dest)));
});

Просмотреть файл

@ -7,9 +7,9 @@ const replace = require('gulp-replace');
// Copy across all original Sass source files for distribution.
function copySass() {
let tasks = [];
const tasks = [];
Object.keys(config).forEach((key) => {
let val = config[key];
const val = config[key];
tasks.push(gulp.src(val.src)
.pipe(replace('./node_modules/@mozilla-protocol/', ''))
.pipe(gulp.dest(val.dest))

Просмотреть файл

@ -6,9 +6,9 @@ const merge = require('merge-stream');
// Copy across all static assets for both Protocol and docs.
function copyStaticFiles() {
let tasks = [];
const tasks = [];
Object.keys(config).forEach((key) => {
let val = config[key];
const val = config[key];
tasks.push(gulp.src(val.src).pipe(gulp.dest(val.dest)));
});

Просмотреть файл

@ -5,7 +5,7 @@ const path = require('path');
function readDirRecursive(dir, subdir='', key='general icons') {
let output = {
const output = {
[key]:{
files:[],
subsets:[]

Просмотреть файл

@ -3,7 +3,7 @@
const notify = require('gulp-notify');
module.exports = function() {
let args = Array.prototype.slice.call(arguments);
const args = Array.prototype.slice.call(arguments);
// Send error to notification center with gulp-notify
notify.onError({

3889
package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -16,19 +16,24 @@
"scripts": {
"prestart": "npm install && npm run lint",
"start": "gulp --dev",
"build": "npm run prestart && gulp build",
"webpack": "webpack --config webpack.static.config.js --mode development && webpack --config webpack.build.config.js --mode development",
"build": "npm run prestart && npm run webpack",
"lint-css": "./node_modules/.bin/stylelint \"src/assets/sass/**/*.scss\" ",
"lint-js": "./node_modules/.bin/eslint \"src/assets/js/**/*.js\" \"gulpfile.js/**/*.js\" ",
"lint": "npm run lint-js && npm run lint-css",
"lint-js": "./node_modules/.bin/eslint \"src/assets/js/**/*.js\" \"gulpfile.js/**/*.js\" \"webpack.static.config.js\" \"webpack.build.config.js\" ",
"lint": "npm run lint-js && npm run lint-css ",
"test": "./node_modules/.bin/karma start ./tests/karma.conf.js",
"pretest": "npm run build",
"docs": "doctoc --title \"### Contents\" --maxlevel 2 docs/README.md",
"prepublishOnly": "gulp build"
"prepublishOnly": "npm run webpack"
},
"dependencies": {
"@cloudfour/hbs-helpers": "^0.9.0",
"@mozilla-protocol/assets": "^5.1.0",
"@mozilla-protocol/tokens": "^5.0.5",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^10.0.0",
"css-loader": "^6.5.1",
"css-minimizer-webpack-plugin": "^3.2.0",
"del": "^6.0.0",
"drizzle-builder": "0.0.10",
"gulp": "^4.0.2",
@ -44,13 +49,17 @@
"gulp-uglify": "^3.0.2",
"gulp-util": "^3.0.8",
"merge-stream": "^2.0.0",
"mini-css-extract-plugin": "^2.4.5",
"prismjs": "^1.25.0",
"require-dir": "^1.2.0",
"sass": "^1.41.1",
"sass-loader": "^12.4.0",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1",
"webpack-remove-empty-scripts": "^0.7.1",
"yargs": "^17.1.1"
},
"devDependencies": {
"@mozilla-protocol/eslint-config": "^1.1.0",
"ansi-regex": ">=6.0.1",
"axios": ">=0.21.2",
"browser-sync": "^2.27.5",

23
src/.eslintrc.js Normal file
Просмотреть файл

@ -0,0 +1,23 @@
module.exports = {
env: {
'browser': true,
'node': false,
'commonjs': false,
'es2017': false
},
extends: [
'eslint:recommended'
],
rules: {
// Require strict mode directive in top level functions
// https://eslint.org/docs/rules/strict
'strict': ['error', 'function'],
// Require `let` or `const` instead of `var`
// https://eslint.org/docs/rules/no-var
'no-var': 'off',
},
globals: {
'Mzp': 'writable'
}
};

11
src/main.js Normal file
Просмотреть файл

@ -0,0 +1,11 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
/**
* This file serves as an entry point for webpack.static.config.js.
* It is not required by any Protocol component files but should
* not be deleted.
*/

Просмотреть файл

@ -20,14 +20,14 @@ module.exports = function(config) {
// list of files / patterns to load in the browser
files: [
// library
'../dist/assets/protocol/protocol/js/protocol-supports.js',
'../dist/assets/protocol/protocol/js/protocol-utils.js',
'../package/protocol/js/protocol-supports.js',
'../package/protocol/js/protocol-utils.js',
// js files
'../dist/assets/protocol/protocol/js/protocol-details.js',
'../dist/assets/protocol/protocol/js/protocol-lang-switcher.js',
'../dist/assets/protocol/protocol/js/protocol-menu.js',
'../dist/assets/protocol/protocol/js/protocol-navigation.js',
'../dist/assets/protocol/protocol/js/protocol-notification-bar.js',
'../package/protocol/js/protocol-details.js',
'../package/protocol/js/protocol-lang-switcher.js',
'../package/protocol/js/protocol-menu.js',
'../package/protocol/js/protocol-navigation.js',
'../package/protocol/js/protocol-notification-bar.js',
// tests
'unit/protocol-details.js',
'unit/protocol-lang-switcher.js',

99
webpack.build.config.js Normal file
Просмотреть файл

@ -0,0 +1,99 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
/* eslint-env node, commonjs, es2017 */
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');
const TerserPlugin = require('terser-webpack-plugin');
const glob = require('glob');
const path = require('path');
// Create both uncompressed and minified JS assets for each file in directory.
const jsConfig = {
devtool: false,
entry: glob.sync('./src/assets/js/protocol/*.js').reduce((obj, el) => {
const name = path.parse(el).name;
obj[name] = el;
obj[`${name}.min`] = el;
return obj;
}, {}),
output: {
path: path.resolve(__dirname, 'package/protocol/js'),
filename: '[name].js'
},
performance: {
hints: 'warning'
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
include: /\.min\.js$/,
extractComments: false
}),
],
}
};
// Create both uncompressed and minified CSS assets for standard Protocol libraries.
const cssConfig = {
entry: {
'protocol': path.resolve(__dirname, 'src/assets/sass/protocol/protocol.scss'),
'protocol.min': path.resolve(__dirname, 'src/assets/sass/protocol/protocol.scss'),
'protocol-components': path.resolve(__dirname, 'src/assets/sass/protocol/protocol-components.scss'),
'protocol-components.min': path.resolve(__dirname, 'src/assets/sass/protocol/protocol-components.scss'),
},
output: {
filename: 'temp/[name].js',
path: path.resolve(__dirname, 'package/protocol/css'),
},
devtool: 'source-map',
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin({
include: /\.min\.css$/
}),
],
},
module: {
rules: [
{
test: /\.scss$/,
include: path.resolve(__dirname, 'src/assets/sass/protocol'),
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: false,
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
]
}
]
},
performance: {
hints: 'warning'
},
plugins: [
// Remove empty JS files that are left over once CSS has been extracted.
new RemoveEmptyScriptsPlugin(),
new MiniCssExtractPlugin()
]
};
module.exports = [cssConfig, jsConfig];

58
webpack.static.config.js Normal file
Просмотреть файл

@ -0,0 +1,58 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
/* eslint-env node, commonjs, es2017 */
const CopyPlugin = require('copy-webpack-plugin');
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// Copy static assets to the `./package/ directory for publishing.
module.exports = {
// main.js serves as an entrypoint for Webpack, but is not required
// directly by any Protocol components.
entry: path.resolve(__dirname, 'src/main.js'),
output: {
path: path.resolve(__dirname, 'package')
},
performance: {
hints: 'warning'
},
devtool: false,
plugins: [
// Clean out ./package directory before processing.
new CleanWebpackPlugin(),
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, 'src/assets/sass/protocol'),
to: 'protocol/css/',
transform: (content) => {
// This is required so that _lib.scss can load the tokens package
// using a relative @import, as opposed to the main Protocol package
// needing to distribute its own set of node_modules dependencies.
return content.toString().replace('./node_modules/@mozilla-protocol/', '');
}
},
{
from: path.resolve(__dirname, 'src/assets/fonts/'),
to: 'protocol/fonts/'
},
{
from: path.resolve(__dirname, 'src/assets/package/')
},
{
from: path.resolve(__dirname, 'node_modules/@mozilla-protocol/tokens/dist/'),
to: 'protocol/css/includes/tokens/dist/'
},
{
from: path.resolve(__dirname, 'node_modules/@mozilla-protocol/assets/'),
to: 'protocol/img/'
}
]
})
]
};