Replacing REMARK_URL, fix remark_config stub, add minify html/css in templates

This commit is contained in:
Pavel Mineev
2021-01-12 13:39:26 -06:00
committed by Umputun
parent e77ffef4f4
commit bb5907d21f
14 changed files with 222 additions and 106 deletions
+2 -1
View File
@@ -42,7 +42,8 @@ COPY --from=build-frontend /srv/frontend/public/ web
RUN \
export WEB_ROOT=/build/backend/web && \
sed -i "s|https://demo.remark42.com|http://127.0.0.1:8080|g" ${WEB_ROOT}/*.js && \
sed -i "s|{% REMARK_URL %}http://127.0.0.1:8080|g" ${WEB_ROOT}/*.js && \
sed -i "s|{% REMARK_URL %}http://127.0.0.1:8080|g" ${WEB_ROOT}/*.html && \
statik --src=${WEB_ROOT} --dest=/build/backend/app/rest -p api -f && \
statik --src=/build/backend/templates --dest=/build/backend/app -p templates -ns templates -f && \
ls -la /build/backend/app/templates/statik.go && \
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
echo "prepare environment"
# replace BASE_URL constant by REMARK_URL
# replace {% REMARK_URL %} by content of REMARK_URL variable
sed -i "s|{% REMARK_URL %}|${REMARK_URL}|g" /srv/web/*.html
sed -i "s|{% REMARK_URL %}|${REMARK_URL}|g" /srv/web/*.js
+4
View File
@@ -0,0 +1,4 @@
window.remark_config = {
host: 'http://test.com',
site_id: 'remark',
};
+1 -1
View File
@@ -1,4 +1,4 @@
export const BASE_URL = (window.remark_config && window.remark_config.host) || process.env.REMARK_URL!;
export const BASE_URL = window.remark_config.host;
export const NODE_ID = process.env.REMARK_NODE!;
export const API_BASE = '/api/v1';
export const COMMENT_NODE_CLASSNAME_PREFIX = 'remark42__comment-';
+4 -3
View File
@@ -43,7 +43,7 @@ const fetcher = methods.reduce<Partial<FetcherObject>>((acc, method) => {
contentType = 'application/json',
logError = true,
} = typeof data === 'string' ? { url: data } : data;
const basename = `${BASE_URL}${overriddenApiBase}`;
const baseUrl = `${BASE_URL}${overriddenApiBase}`;
const headers = new Headers({
Accept: 'application/json',
@@ -54,11 +54,12 @@ const fetcher = methods.reduce<Partial<FetcherObject>>((acc, method) => {
headers.append('Content-Type', contentType);
}
// Save token in memory and pass it into headers in case if storing cookies is disabled
if (activeJwtToken) {
headers.append(HEADER_X_JWT, activeJwtToken);
}
let rurl = `${basename}${url}`;
let rurl = `${baseUrl}${url}`;
const parameters: RequestInit = {
method,
@@ -118,7 +119,7 @@ const fetcher = methods.reduce<Partial<FetcherObject>>((acc, method) => {
});
}
if (res.headers.has('Content-Type') && res.headers.get('Content-Type')!.indexOf('application/json') === 0) {
if (res.headers.get('Content-Type')?.startsWith('application/json')) {
return res.json();
}
@@ -1,4 +1,3 @@
import './list-comments.css';
import './__item/list-comments__item.css';
export { default } from './list-comments';
@@ -1,5 +1,6 @@
import { h, FunctionComponent } from 'preact';
import { useIntl } from 'react-intl';
import classnames from 'classnames';
import type { Comment as CommentType } from 'common/types';
import Comment from 'components/comment';
@@ -14,7 +15,7 @@ const ListComments: FunctionComponent<ListCommentsProps> = ({ comments = [] }) =
const intl = useIntl();
return (
<div className={styles.root}>
<div className={classnames('comments-list', styles.root)}>
{comments.map(comment => (
<Comment
intl={intl}
+5 -9
View File
@@ -22,27 +22,23 @@ async function init(): Promise<void> {
const nodes = document.getElementsByClassName(LAST_COMMENTS_NODE_CLASSNAME);
if (!nodes) {
console.error("Remark42: Can't find last comments nodes.");
return;
throw new Error("Remark42: Can't find last comments nodes.");
}
try {
window.remark_config = window.remark_config || {};
} catch (e) {
console.error('Remark42: Config object is undefined.');
return;
if (!window.remark_config) {
throw new Error('Remark42: Config object is undefined');
}
const { site_id, max_last_comments } = window.remark_config;
if (!site_id) {
console.error('Remark42: Site ID is undefined.');
return;
throw new Error('Remark42: Site ID is undefined.');
}
(Array.from(nodes) as HTMLElement[]).forEach(node => {
const max = (node.dataset.max && parseInt(node.dataset.max, 10)) || max_last_comments || DEFAULT_LAST_COMMENTS_MAX;
const locale = getLocale(window.remark_config);
Promise.all([getLastComments(site_id, max), loadLocale(locale)]).then(([comments, messages]) => {
try {
render(
+1
View File
@@ -19,6 +19,7 @@ module.exports = {
setupFilesAfterEnv: [
'jest-localstorage-mock',
'<rootDir>/app/__mocks__/headers.ts',
'<rootDir>/app/__stubs__/remark-config.ts',
'<rootDir>/app/__stubs__/static-config.ts',
],
collectCoverageFrom: ['!**/__mocks__/**', '!**/__stubs__/**', '!app/locales/**'],
+3 -3
View File
@@ -5,12 +5,12 @@
"scripts": {
"build": "webpack --mode production",
"build:analyze": "webpack --mode production --analyze",
"start": "webpack serve --mode development",
"dev": "cross-env REMARK_URL=http://127.0.0.1:8080 run-s npm start",
"start": "cross-env REMARK_API_BASE_URL=https://demo.remark42.com webpack serve --mode development",
"dev": "cross-env REMARK_URL=http://127.0.0.1:8080 webpack serve --mode development",
"lint": "run-p lint:*",
"test": "jest",
"test:coverage": "jest --coverage",
"check": "cross-env NODE_ENV=production npm run build && run-p check:*",
"check": "cross-env NODE_ENV=production run-s build && run-p check:*",
"check:types": "tsc -p tsconfig.json --noEmit",
"check:translation": "run-s translation:extract translation:check",
"check:size": "size-limit",
+84
View File
@@ -0,0 +1,84 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Remark42 demo</title>
<style>
/* stylelint-disable mavrin/stylelint-declaration-use-css-custom-properties */
body {
margin: 0;
padding: 20px;
text-align: center;
font: 18px/24px Helvetica, Arial, sans-serif;
color: #333;
}
article {
display: block;
text-align: left;
max-width: 640px;
margin: 0 auto;
}
h1 {
font-size: 50px;
margin-left: -0.05em;
}
ul {
color: rgb(23, 67, 78);
}
a {
color: rgb(79, 187, 214);
text-decoration: none;
}
a:hover {
color: rgb(94, 167, 177);
text-decoration: underline;
}
</style>
</head>
<body>
<article>
<h1><a href="https://remark42.com/">Remark42</a></h1>
<p id="title"></p>
<div id="remark42"></div>
</article>
<script>
var query = (function() {
if (window.location.search.length === 0) return {};
return window.location.search
.substr(1)
.split('&')
.map(function(item) {
return item.split('=');
})
.reduce(function(carry, item) {
carry[item[0]] = decodeURIComponent(item[1]);
return carry;
}, {});
})();
if (query.site_id && query.url) {
var titleElement = document.getElementById('title');
titleElement.innerHTML = 'Comments for <a href="' + query.url + '">' + query.url + '</a>';
var remark_config = {
site_id: query.site_id,
host: '<%= htmlWebpackPlugin.options.REMARK_URL %>',
url: query.url
};
(function(c) {
for(var i = 0; i < c.length; i++){
var d = document, s = d.createElement('script');
s.src = remark_config.host + '/web/' +c[i] +'.js';
(d.head || d.body).appendChild(s);
}
})(remark_config.components || ['embed']);
}
</script>
<noscript> Please enable JavaScript to view the comments powered by Remark. </noscript>
</body>
</html>
+2 -1
View File
@@ -6,6 +6,7 @@
<title>Delete Me</title>
<base target="_blank" />
<style>
/* stylelint-disable mavrin/stylelint-declaration-use-css-custom-properties */
html,
body {
-webkit-font-smoothing: antialiased;
@@ -35,7 +36,7 @@
}
.preloader {
color: #fff; /* stylelint-disable */
color: #fff;
position: relative;
transform: translateZ(0);
animation-delay: -0.16s;
+1
View File
@@ -15,6 +15,7 @@
"baseUrl": "app" ,
"esModuleInterop": true,
"skipLibCheck": true,
"sourceMap": true
},
"include": ["app/typings", "app/**/*.tsx", "app/**/*.ts"],
"exclude": ["node_modules"]
+112 -85
View File
@@ -11,11 +11,20 @@ const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const babelConfig = require('./.babelrc.js');
const NODE_ID = 'remark42';
const REMARK_URL = '{% REMARK_URL %}';
const PUBLIC_PATH = '/web';
const PORT = process.env.PORT || 9000;
const REMARK_API_BASE_URL = process.env.REMARK_API_BASE_URL || 'http://127.0.0.1:8080';
const DEVSERVER_BASE_PATH = process.env.DEVSERVER_BASE_PATH || 'http://127.0.0.1:9000';
const PUBLIC_FOLDER_PATH = path.resolve(__dirname, 'public');
const CUSTOM_PROPERTIES_PATH = path.resolve(__dirname, './app/custom-properties.css');
/**
* Generates excludes for babel-loader
*
* Exclude is a module that has >=es6 code and resides in node_modules.
* By defaut babel-loader ignores everything from node_modules,
* so we have to exclude from ignore these modules
*/
const exclude = [
'@github/markdown-toolbar-element',
'@github/text-expander-element',
@@ -24,10 +33,28 @@ const exclude = [
'intl-messageformat-parser',
].map(m => path.resolve(__dirname, 'node_modules', m));
module.exports = (_, { mode, analyze, env }) => {
const isDev = mode === 'development';
const htmlMinifyOptions = {
minifyCSS: true,
minifyJS: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
sortAttributes: true,
sortClassName: true,
useShortDoctype: true,
};
module.exports = (_, { mode, analyze }) => {
const isDev = mode === 'development';
// Use REMARK_URL or predefined host in dev environment
// In development: We use `http://127.0.0.1:9000` for access to backend and backend is accessable via dev server proxy
// In production: {% REMARK_URL %} will be replaced by `sed` on start of prod
const REMARK_URL = isDev ? DEVSERVER_BASE_PATH : '{% REMARK_URL %}';
// Add debug lib only for developmet throw webpack chuncks and keep code clear
const preactDebug = isDev ? ['preact/debug'] : [];
const entry = {
embed: './app/embed.ts',
counter: './app/counter.ts',
@@ -61,10 +88,12 @@ module.exports = (_, { mode, analyze, env }) => {
const getTsRule = (babelEnvConfig = {}) => {
return {
test: /\.tsx?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
exclude,
cacheDirectory: true,
...babelEnvConfig,
},
@@ -76,20 +105,12 @@ module.exports = (_, { mode, analyze, env }) => {
},
},
],
/**
* Generates excludes for babel-loader
*
* Exclude is a module that has >=es6 code and resides in node_modules.
* By defaut babel-loader ignores everything from node_modules,
* so we have to exclude from ignore these modules
*/
exclude,
};
};
const cssRule = {
test: /\.css$/,
exclude: /\.module\.css$/,
exclude: [/\.module\.css$/, /node_modules/],
use: [
isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
@@ -110,6 +131,7 @@ module.exports = (_, { mode, analyze, env }) => {
const cssModulesRule = {
test: /\.module\.css$/,
exclude: /node_modules/,
use: [
isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
{
@@ -138,81 +160,21 @@ module.exports = (_, { mode, analyze, env }) => {
const fileRule = {
test: /\.(png|jpg|jpeg|gif|svg)$/,
exclude: /node_modules/,
use: {
loader: 'file-loader',
options: {
name: isDev ? 'files/[name].[contenthash].[ext]' : 'files/[contenthash:6].[ext]',
name: '[name].[ext]',
publicPath: PUBLIC_PATH,
},
},
};
const rules = [cssRule, cssModulesRule, fileRule];
const plugins = [
...(isDev
? [
new CleanWebpackPlugin(),
new RefreshPlugin(),
new webpack.ProgressPlugin(),
new webpack.HotModuleReplacementPlugin(),
]
: []),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(mode),
'process.env.REMARK_NODE': JSON.stringify(NODE_ID),
'process.env.REMARK_URL': isDev ? 'window.location.origin' : JSON.stringify(REMARK_URL),
}),
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new ForkTsCheckerWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/iframe.ejs'),
filename: 'iframe.html',
inject: false,
env: mode,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/demo.ejs'),
filename: 'index.html',
inject: false,
REMARK_URL,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/counter.ejs'),
filename: 'counter.html',
inject: false,
REMARK_URL,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/last-comments.ejs'),
filename: 'last-comments.html',
inject: false,
REMARK_URL,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/deleteme.ejs'),
filename: 'deleteme.html',
inject: false,
REMARK_URL,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/markdown-help.html'),
filename: 'markdown-help.html',
inject: false,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/privacy.html'),
filename: 'privacy.html',
inject: false,
}),
];
const devServer = {
host: '0.0.0.0',
port: process.env.PORT || 9000,
port: PORT,
contentBase: PUBLIC_FOLDER_PATH,
publicPath: PUBLIC_PATH,
disableHostCheck: true,
historyApiFallback: true,
quiet: true,
@@ -223,20 +185,31 @@ module.exports = (_, { mode, analyze, env }) => {
overlay: false,
stats: 'minimal',
watchOptions: {
ignored: [path.resolve(__dirname, 'build'), path.resolve(__dirname, 'node_modules')],
ignored: [PUBLIC_FOLDER_PATH, path.resolve(__dirname, 'node_modules')],
},
proxy: [
{ path: '/api', target: REMARK_URL, changeOrigin: true },
{ path: '/auth', target: REMARK_URL, changeOrigin: true },
{ path: '/api', target: REMARK_API_BASE_URL, changeOrigin: true },
{ path: '/auth', target: REMARK_API_BASE_URL, changeOrigin: true },
],
};
const plugins = [
...(isDev ? [new CleanWebpackPlugin(), new RefreshPlugin(), new webpack.HotModuleReplacementPlugin()] : []),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(mode),
'process.env.REMARK_NODE': JSON.stringify(NODE_ID),
'process.env.REMARK_URL': isDev ? 'window.location.origin' : JSON.stringify(REMARK_URL),
}),
new MiniCssExtractPlugin({
filename: '[name].css',
}),
];
const config = {
entry,
devtool: 'source-map',
resolve,
optimization,
stats: 'minimal',
devServer: env.WEBPACK_SERVE && devServer,
};
const legacyConfig = {
@@ -275,6 +248,63 @@ module.exports = (_, { mode, analyze, env }) => {
},
plugins: [
...plugins,
new ForkTsCheckerWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/iframe.ejs'),
filename: 'iframe.html',
inject: false,
env: mode,
minify: htmlMinifyOptions,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/demo.ejs'),
filename: 'index.html',
inject: false,
REMARK_URL,
minify: htmlMinifyOptions,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/counter.ejs'),
filename: 'counter.html',
inject: false,
REMARK_URL,
minify: htmlMinifyOptions,
}),
// new HtmlWebpackPlugin({
// template: path.resolve(__dirname, 'templates/comments.ejs'),
// filename: 'comments.html',
// inject: false,
// env: mode,
// REMARK_URL,
// minify: htmlMinifyOptions,
// }),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/last-comments.ejs'),
filename: 'last-comments.html',
inject: false,
env: mode,
REMARK_URL,
minify: htmlMinifyOptions,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/deleteme.ejs'),
filename: 'deleteme.html',
inject: false,
REMARK_URL,
minify: htmlMinifyOptions,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/markdown-help.html'),
filename: 'markdown-help.html',
inject: false,
minify: htmlMinifyOptions,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'templates/privacy.html'),
filename: 'privacy.html',
inject: false,
minify: htmlMinifyOptions,
}),
...(analyze
? [
new BundleAnalyzerPlugin({
@@ -285,12 +315,9 @@ module.exports = (_, { mode, analyze, env }) => {
]
: []),
],
devServer,
};
if (isDev) {
return modernConfig;
}
return [legacyConfig, modernConfig];
};
module.exports.CUSTOM_PROPERTIES_PATH = CUSTOM_PROPERTIES_PATH;