mirror of https://github.com/keeweb/keeweb.git
building css with webpack
This commit is contained in:
parent
32b4e99c12
commit
a7096b5cdf
46
Gruntfile.js
46
Gruntfile.js
|
@ -1,11 +1,9 @@
|
||||||
/* eslint-env node */
|
/* eslint-env node */
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
const sass = require('node-sass');
|
|
||||||
|
|
||||||
const webpackConfig = require('./webpack.config');
|
const webpackConfig = require('./webpack.config');
|
||||||
const postCssReplaceFont = require('./build/util/postcss-replace-font');
|
|
||||||
const pkg = require('./package.json');
|
const pkg = require('./package.json');
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
|
@ -148,30 +146,6 @@ module.exports = function(grunt) {
|
||||||
desktop: ['desktop/**/*.js', '!desktop/node_modules/**'],
|
desktop: ['desktop/**/*.js', '!desktop/node_modules/**'],
|
||||||
grunt: ['Gruntfile.js', 'grunt/**/*.js']
|
grunt: ['Gruntfile.js', 'grunt/**/*.js']
|
||||||
},
|
},
|
||||||
sass: {
|
|
||||||
options: {
|
|
||||||
sourceMap: false,
|
|
||||||
includePaths: ['./node_modules'],
|
|
||||||
implementation: sass
|
|
||||||
},
|
|
||||||
dist: {
|
|
||||||
files: {
|
|
||||||
'tmp/css/main.css': 'app/styles/main.scss'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
postcss: {
|
|
||||||
options: {
|
|
||||||
processors: [
|
|
||||||
postCssReplaceFont,
|
|
||||||
require('cssnano')({discardComments: {removeAll: true}})
|
|
||||||
]
|
|
||||||
},
|
|
||||||
dist: {
|
|
||||||
src: 'tmp/css/main.css',
|
|
||||||
dest: 'tmp/css/main.css'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
inline: {
|
inline: {
|
||||||
app: {
|
app: {
|
||||||
src: 'tmp/index.html',
|
src: 'tmp/index.html',
|
||||||
|
@ -222,8 +196,9 @@ module.exports = function(grunt) {
|
||||||
},
|
},
|
||||||
'webpack-dev-server': {
|
'webpack-dev-server': {
|
||||||
options: {
|
options: {
|
||||||
webpack: webpackConfig.devServerConfig(grunt),
|
webpack: webpackConfig.config(grunt, 'development'),
|
||||||
publicPath: '/tmp/js',
|
publicPath: '/',
|
||||||
|
contentBase: path.resolve(__dirname, 'tmp'),
|
||||||
progress: false
|
progress: false
|
||||||
},
|
},
|
||||||
js: {
|
js: {
|
||||||
|
@ -251,10 +226,6 @@ module.exports = function(grunt) {
|
||||||
interrupt: true,
|
interrupt: true,
|
||||||
debounceDelay: 500
|
debounceDelay: 500
|
||||||
},
|
},
|
||||||
styles: {
|
|
||||||
files: 'app/styles/**/*.scss',
|
|
||||||
tasks: ['sass']
|
|
||||||
},
|
|
||||||
indexhtml: {
|
indexhtml: {
|
||||||
files: 'app/index.html',
|
files: 'app/index.html',
|
||||||
tasks: ['copy:html']
|
tasks: ['copy:html']
|
||||||
|
@ -549,15 +520,6 @@ module.exports = function(grunt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'concurrent': {
|
|
||||||
options: {
|
|
||||||
logConcurrentOutput: true
|
|
||||||
},
|
|
||||||
'dev-server': [
|
|
||||||
'watch:styles',
|
|
||||||
'webpack-dev-server'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
'sign-dist': {
|
'sign-dist': {
|
||||||
'dist': {
|
'dist': {
|
||||||
options: {
|
options: {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
<link rel="apple-touch-startup-image" href="icons/splash-1668x2224.png" media="(min-device-width: 834px) and (max-device-width: 834px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
|
<link rel="apple-touch-startup-image" href="icons/splash-1668x2224.png" media="(min-device-width: 834px) and (max-device-width: 834px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||||
<link rel="apple-touch-startup-image" href="icons/splash-2048x2732.png" media="(min-device-width: 1024px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
|
<link rel="apple-touch-startup-image" href="icons/splash-2048x2732.png" media="(min-device-width: 1024px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
<link rel="stylesheet" href="css/main.css?__inline=true" />
|
<link rel="stylesheet" href="css/app.css?__inline=true" />
|
||||||
<script src="js/vendor.js?__inline=true"></script>
|
<script src="js/vendor.js?__inline=true"></script>
|
||||||
<script src="js/app.js?__inline=true"></script>
|
<script src="js/app.js?__inline=true"></script>
|
||||||
<script src="js/runtime.js?__inline=true"></script>
|
<script src="js/runtime.js?__inline=true"></script>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
@import "../node_modules/normalize.css/normalize";
|
$fa-font-path: '~font-awesome/fonts';
|
||||||
@import "../node_modules/font-awesome/scss/font-awesome";
|
|
||||||
@import "../node_modules/pikaday/scss/pikaday";
|
@import "~normalize.css/normalize";
|
||||||
@import "../node_modules/bourbon/app/assets/stylesheets/bourbon";
|
@import "~font-awesome/scss/font-awesome";
|
||||||
|
@import "~pikaday/scss/pikaday";
|
||||||
|
@import "~bourbon/app/assets/stylesheets/bourbon";
|
||||||
|
|
||||||
@import "themes/all-themes";
|
@import "themes/all-themes";
|
||||||
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
function replaceFont(css) {
|
|
||||||
css.walkAtRules('font-face', rule => {
|
|
||||||
const fontFamily = rule.nodes.filter(n => n.prop === 'font-family')[0];
|
|
||||||
if (!fontFamily) {
|
|
||||||
throw 'Bad font rule: ' + rule.toString();
|
|
||||||
}
|
|
||||||
const value = fontFamily.value.replace(/["']/g, '');
|
|
||||||
const fontFiles = {
|
|
||||||
FontAwesome: 'fontawesome-webfont.woff'
|
|
||||||
};
|
|
||||||
const fontFile = fontFiles[value];
|
|
||||||
if (!fontFile) {
|
|
||||||
throw 'Unsupported font ' + value + ': ' + rule.toString();
|
|
||||||
}
|
|
||||||
const data = fs.readFileSync('tmp/fonts/' + fontFile, 'base64');
|
|
||||||
const src = 'url(data:application/font-woff;charset=utf-8;base64,{data}) format(\'woff\')'
|
|
||||||
.replace('{data}', data);
|
|
||||||
rule.nodes = rule.nodes.filter(n => n.prop !== 'src');
|
|
||||||
rule.append({ prop: 'src', value: src });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = replaceFont;
|
|
|
@ -10,7 +10,7 @@ module.exports = function(grunt) {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
grunt.registerTask('devsrv', 'Start web server and watcher', [
|
grunt.registerTask('devsrv', 'Start web server and watcher', [
|
||||||
'concurrent:dev-server'
|
'webpack-dev-server'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
grunt.registerTask('desktop', 'Build web and desktop apps for all platforms', [
|
grunt.registerTask('desktop', 'Build web and desktop apps for all platforms', [
|
||||||
|
|
|
@ -10,8 +10,6 @@ module.exports = function(grunt) {
|
||||||
'copy:fonts',
|
'copy:fonts',
|
||||||
'webpack',
|
'webpack',
|
||||||
'uglify',
|
'uglify',
|
||||||
'sass',
|
|
||||||
'postcss',
|
|
||||||
'inline',
|
'inline',
|
||||||
'htmlmin',
|
'htmlmin',
|
||||||
'string-replace:manifest-html',
|
'string-replace:manifest-html',
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
|
@ -18,7 +18,6 @@
|
||||||
"baron": "2.2.2",
|
"baron": "2.2.2",
|
||||||
"base64-loader": "1.0.0",
|
"base64-loader": "1.0.0",
|
||||||
"bourbon": "4.2.7",
|
"bourbon": "4.2.7",
|
||||||
"cssnano": "4.1.8",
|
|
||||||
"electron": "^4.0.1",
|
"electron": "^4.0.1",
|
||||||
"eslint": "^5.12.0",
|
"eslint": "^5.12.0",
|
||||||
"eslint-config-standard": "12.0.0",
|
"eslint-config-standard": "12.0.0",
|
||||||
|
@ -29,7 +28,6 @@
|
||||||
"exports-loader": "0.7.0",
|
"exports-loader": "0.7.0",
|
||||||
"font-awesome": "4.7.0",
|
"font-awesome": "4.7.0",
|
||||||
"grunt": "1.0.3",
|
"grunt": "1.0.3",
|
||||||
"grunt-concurrent": "2.3.1",
|
|
||||||
"grunt-contrib-clean": "2.0.0",
|
"grunt-contrib-clean": "2.0.0",
|
||||||
"grunt-contrib-compress": "1.4.3",
|
"grunt-contrib-compress": "1.4.3",
|
||||||
"grunt-contrib-copy": "1.0.0",
|
"grunt-contrib-copy": "1.0.0",
|
||||||
|
@ -41,24 +39,25 @@
|
||||||
"grunt-eslint": "21.0.0",
|
"grunt-eslint": "21.0.0",
|
||||||
"grunt-gitinfo": "github:keeweb/grunt-gitinfo#b61aaed",
|
"grunt-gitinfo": "github:keeweb/grunt-gitinfo#b61aaed",
|
||||||
"grunt-inline-alt": "github:keeweb/grunt-inline-alt#ec9f6ad",
|
"grunt-inline-alt": "github:keeweb/grunt-inline-alt#ec9f6ad",
|
||||||
"grunt-postcss": "0.9.0",
|
|
||||||
"grunt-sass": "3.0.2",
|
|
||||||
"grunt-string-replace": "1.3.1",
|
"grunt-string-replace": "1.3.1",
|
||||||
"grunt-webpack": "3.1.3",
|
"grunt-webpack": "3.1.3",
|
||||||
"handlebars": "4.0.12",
|
"handlebars": "4.0.12",
|
||||||
"handlebars-loader": "1.7.1",
|
"handlebars-loader": "1.7.1",
|
||||||
"html-minifier": "3.5.21",
|
"html-minifier": "3.5.21",
|
||||||
|
"ignore-loader": "^0.1.2",
|
||||||
"jquery": "3.3.1",
|
"jquery": "3.3.1",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"jsqrcode": "github:antelle/jsqrcode#0.1.3",
|
"jsqrcode": "github:antelle/jsqrcode#0.1.3",
|
||||||
"kdbxweb": "1.2.7",
|
"kdbxweb": "1.2.7",
|
||||||
"load-grunt-tasks": "4.0.0",
|
"load-grunt-tasks": "4.0.0",
|
||||||
"node-sass": "^4.12.0",
|
"mini-css-extract-plugin": "^0.8.0",
|
||||||
"node-stream-zip": "1.7.0",
|
"node-stream-zip": "1.7.0",
|
||||||
"normalize.css": "8.0.1",
|
"normalize.css": "8.0.1",
|
||||||
|
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||||
"pikaday": "1.8.0",
|
"pikaday": "1.8.0",
|
||||||
"pkcs15-smartcard-sign": "^1.0.0",
|
"pkcs15-smartcard-sign": "^1.0.0",
|
||||||
"raw-loader": "1.0.0",
|
"raw-loader": "^1.0.0",
|
||||||
|
"sass-loader": "^7.2.0",
|
||||||
"stats-webpack-plugin": "0.7.0",
|
"stats-webpack-plugin": "0.7.0",
|
||||||
"string-replace-webpack-plugin": "0.1.3",
|
"string-replace-webpack-plugin": "0.1.3",
|
||||||
"strip-sourcemap-loader": "0.0.1",
|
"strip-sourcemap-loader": "0.0.1",
|
||||||
|
@ -66,6 +65,7 @@
|
||||||
"time-grunt": "2.0.0",
|
"time-grunt": "2.0.0",
|
||||||
"uglify-loader": "3.0.0",
|
"uglify-loader": "3.0.0",
|
||||||
"uglifyjs-webpack-plugin": "^2.1.1",
|
"uglifyjs-webpack-plugin": "^2.1.1",
|
||||||
|
"url-loader": "^2.1.0",
|
||||||
"webpack": "^4.28.3",
|
"webpack": "^4.28.3",
|
||||||
"webpack-bundle-analyzer": "^3.0.3",
|
"webpack-bundle-analyzer": "^3.0.3",
|
||||||
"webpack-dev-server": "^3.1.14"
|
"webpack-dev-server": "^3.1.14"
|
||||||
|
|
|
@ -5,23 +5,28 @@ const webpack = require('webpack');
|
||||||
const StringReplacePlugin = require('string-replace-webpack-plugin');
|
const StringReplacePlugin = require('string-replace-webpack-plugin');
|
||||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||||
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
|
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||||
|
|
||||||
const pkg = require('./package.json');
|
const pkg = require('./package.json');
|
||||||
|
|
||||||
function config(grunt) {
|
process.noDeprecation = true; // for css loaders
|
||||||
|
|
||||||
|
function config(grunt, mode = 'production') {
|
||||||
|
const devMode = mode === 'development';
|
||||||
const date = grunt.config.get('date');
|
const date = grunt.config.get('date');
|
||||||
const dt = date.toISOString().replace(/T.*/, '');
|
const dt = date.toISOString().replace(/T.*/, '');
|
||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
return {
|
return {
|
||||||
mode: 'production',
|
mode,
|
||||||
entry: {
|
entry: {
|
||||||
app: 'app',
|
app: ['app', 'main.scss'],
|
||||||
vendor: ['jquery', 'underscore', 'backbone', 'kdbxweb', 'baron',
|
vendor: ['jquery', 'underscore', 'backbone', 'kdbxweb', 'baron',
|
||||||
'pikaday', 'jsqrcode', 'argon2-wasm', 'argon2']
|
'pikaday', 'jsqrcode', 'argon2-wasm', 'argon2']
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve('.', 'tmp/js'),
|
path: path.resolve('.', 'tmp'),
|
||||||
filename: '[name].js'
|
filename: 'js/[name].js'
|
||||||
},
|
},
|
||||||
target: 'web',
|
target: 'web',
|
||||||
performance: {
|
performance: {
|
||||||
|
@ -35,16 +40,19 @@ function config(grunt) {
|
||||||
progress: false,
|
progress: false,
|
||||||
failOnError: true,
|
failOnError: true,
|
||||||
resolve: {
|
resolve: {
|
||||||
modules: [path.join(__dirname, 'app/scripts'), path.join(__dirname, 'node_modules')],
|
modules: [
|
||||||
|
path.join(__dirname, 'app/scripts'),
|
||||||
|
path.join(__dirname, 'app/styles'),
|
||||||
|
path.join(__dirname, 'node_modules')
|
||||||
|
],
|
||||||
alias: {
|
alias: {
|
||||||
backbone: 'backbone/backbone-min.js',
|
backbone: `backbone/backbone${devMode ? '-min' : ''}.js`,
|
||||||
underscore: 'underscore/underscore-min.js',
|
underscore: `underscore/underscore${devMode ? '-min' : ''}.js`,
|
||||||
_: 'underscore/underscore-min.js',
|
_: `underscore/underscore${devMode ? '-min' : ''}.js`,
|
||||||
jquery: 'jquery/dist/jquery.min.js',
|
jquery: `jquery/dist/jquery${devMode ? '.min' : ''}.js`,
|
||||||
kdbxweb: 'kdbxweb/dist/kdbxweb.js',
|
kdbxweb: 'kdbxweb/dist/kdbxweb.js',
|
||||||
baron: 'baron/baron.min.js',
|
baron: `baron/baron${devMode ? '.min' : ''}.js`,
|
||||||
pikaday: 'pikaday/pikaday.js',
|
qrcode: `jsqrcode/dist/qrcode${devMode ? '.min' : ''}.js`,
|
||||||
qrcode: 'jsqrcode/dist/qrcode.min.js',
|
|
||||||
argon2: 'argon2-browser/dist/argon2.min.js',
|
argon2: 'argon2-browser/dist/argon2.min.js',
|
||||||
hbs: 'handlebars/runtime.js',
|
hbs: 'handlebars/runtime.js',
|
||||||
'argon2-wasm': 'argon2-browser/dist/argon2.wasm',
|
'argon2-wasm': 'argon2-browser/dist/argon2.wasm',
|
||||||
|
@ -77,7 +85,19 @@ function config(grunt) {
|
||||||
},
|
},
|
||||||
{test: /argon2\.wasm/, type: 'javascript/auto', loader: 'base64-loader'},
|
{test: /argon2\.wasm/, type: 'javascript/auto', loader: 'base64-loader'},
|
||||||
{test: /argon2(\.min)?\.js/, loader: 'raw-loader'},
|
{test: /argon2(\.min)?\.js/, loader: 'raw-loader'},
|
||||||
{test: /\.scss$/, loader: 'raw-loader'}
|
{
|
||||||
|
test: /\.s?css$/,
|
||||||
|
use: [
|
||||||
|
MiniCssExtractPlugin.loader,
|
||||||
|
{ loader: 'css-loader', options: { sourceMap: devMode } },
|
||||||
|
{ loader: 'sass-loader', options: { sourceMap: devMode } }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /fonts\/.*\.(woff2|ttf|eot|svg)/,
|
||||||
|
use: ['raw-loader', 'ignore-loader']
|
||||||
|
},
|
||||||
|
{ test: /\.woff$/, loader: 'url-loader' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
optimization: {
|
optimization: {
|
||||||
|
@ -96,12 +116,17 @@ function config(grunt) {
|
||||||
cache: true,
|
cache: true,
|
||||||
parallel: true
|
parallel: true
|
||||||
}),
|
}),
|
||||||
|
new OptimizeCSSAssetsPlugin({
|
||||||
|
cssProcessorPluginOptions: {
|
||||||
|
preset: ['default', { discardComments: { removeAll: true } }]
|
||||||
|
}
|
||||||
|
}),
|
||||||
new BundleAnalyzerPlugin({
|
new BundleAnalyzerPlugin({
|
||||||
openAnalyzer: false,
|
openAnalyzer: false,
|
||||||
analyzerMode: 'static',
|
analyzerMode: 'static',
|
||||||
reportFilename: '../stats/analyzer_report.html',
|
reportFilename: 'stats/analyzer_report.html',
|
||||||
generateStatsFile: true,
|
generateStatsFile: true,
|
||||||
statsFilename: '../stats/stats.json'
|
statsFilename: 'stats/stats.json'
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -110,7 +135,10 @@ function config(grunt) {
|
||||||
', opensource.org/licenses/' + pkg.license),
|
', opensource.org/licenses/' + pkg.license),
|
||||||
new webpack.ProvidePlugin({_: 'underscore', $: 'jquery'}),
|
new webpack.ProvidePlugin({_: 'underscore', $: 'jquery'}),
|
||||||
new webpack.IgnorePlugin(/^(moment)$/),
|
new webpack.IgnorePlugin(/^(moment)$/),
|
||||||
new StringReplacePlugin()
|
new StringReplacePlugin(),
|
||||||
|
new MiniCssExtractPlugin({
|
||||||
|
filename: 'css/[name].css'
|
||||||
|
})
|
||||||
],
|
],
|
||||||
node: {
|
node: {
|
||||||
console: false,
|
console: false,
|
||||||
|
@ -128,27 +156,9 @@ function config(grunt) {
|
||||||
crypto: 'null',
|
crypto: 'null',
|
||||||
fs: 'null',
|
fs: 'null',
|
||||||
path: 'null'
|
path: 'null'
|
||||||
}
|
},
|
||||||
|
devtool: devMode ? 'source-map' : undefined
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function devServerConfig(grunt) {
|
|
||||||
const devServerConfig = config(grunt);
|
|
||||||
Object.assign(devServerConfig, {
|
|
||||||
mode: 'development',
|
|
||||||
devtool: 'source-map'
|
|
||||||
});
|
|
||||||
Object.assign(devServerConfig.resolve.alias, {
|
|
||||||
backbone: 'backbone/backbone.js',
|
|
||||||
underscore: 'underscore/underscore.js',
|
|
||||||
_: 'underscore/underscore.js',
|
|
||||||
jquery: 'jquery/dist/jquery.js',
|
|
||||||
baron: 'baron/baron.js',
|
|
||||||
qrcode: 'jsqrcode/dist/qrcode.js',
|
|
||||||
argon2: 'argon2-browser/dist/argon2.js'
|
|
||||||
});
|
|
||||||
return devServerConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.config = config;
|
module.exports.config = config;
|
||||||
module.exports.devServerConfig = devServerConfig;
|
|
||||||
|
|
Loading…
Reference in New Issue