chore: use @rollup/plugin-strip to remove console.log and perf marks/measures (#136)

* fix: use @rollup/plugin-strip

* fix: progress

* test: fix test

* fix: fixup
This commit is contained in:
Nolan Lawson 2021-05-31 08:45:59 -07:00 committed by GitHub
parent 3b0cfe57f7
commit f6f5d93780
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 83 additions and 94 deletions

View File

@ -4,6 +4,16 @@ import FDBKeyRange from 'fake-indexeddb/build/FDBKeyRange'
import { Crypto } from '@peculiar/webcrypto'
import { ResizeObserver } from 'd2l-resize-aware/resize-observer-module.js'
if (!global.performance) {
global.performance = {}
}
if (!global.performance.mark) {
global.performance.mark = () => {}
}
if (!global.performance.measure) {
global.performance.measure = () => {}
}
jest.mock('node-fetch', () => require('fetch-mock-jest').sandbox())
jest.setTimeout(60000)
@ -15,6 +25,13 @@ global.ResizeObserver = ResizeObserver
process.env.NODE_ENV = 'test'
global.IDBKeyRange = FDBKeyRange
beforeAll(() => {
jest.spyOn(global.console, 'log').mockImplementation()
jest.spyOn(global.console, 'warn').mockImplementation()
jest.spyOn(global.console, 'error').mockImplementation()
})
beforeEach(() => {
global.indexedDB = new FDBFactory() // fresh indexedDB for every test
})

View File

@ -72,6 +72,7 @@
"@rollup/plugin-commonjs": "^16.0.0",
"@rollup/plugin-node-resolve": "^10.0.0",
"@rollup/plugin-replace": "^2.3.4",
"@rollup/plugin-strip": "^2.0.1",
"@testing-library/dom": "^7.29.0",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/user-event": "^12.6.0",

View File

@ -1,13 +1,15 @@
import cjs from '@rollup/plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
import replace from '@rollup/plugin-replace'
import strip from '@rollup/plugin-strip'
import mainSvelte from 'rollup-plugin-svelte'
import hotSvelte from 'rollup-plugin-svelte-hot'
import preprocess from 'svelte-preprocess'
import analyze from 'rollup-plugin-analyzer'
import cssnano from 'cssnano'
const dev = process.env.NODE_ENV !== 'production'
const { NODE_ENV } = process.env
const dev = NODE_ENV !== 'production'
const svelte = dev ? hotSvelte : mainSvelte
const preprocessConfig = preprocess({
@ -58,6 +60,13 @@ const baseConfig = {
dev,
preprocess: preprocessConfig
}),
strip({
include: ['**/*.js', '**/*.svelte'],
functions: [
(!dev && !process.env.PERF) && 'performance.*',
!dev && 'console.log'
].filter(Boolean)
}),
!dev && analyze({ summaryOnly: true })
],
external: [

View File

@ -18,7 +18,6 @@ import {
getEmojiBySearchQuery, getEmojiByShortcode, getEmojiByUnicode,
get, set, getTopFavoriteEmoji, incrementFavoriteEmojiCount
} from './idbInterface'
import { log } from '../shared/log'
import { customEmojiIndex } from './customEmojiIndex'
import { cleanEmoji } from './utils/cleanEmoji'
import { loadDataForFirstTime, checkForUpdates } from './dataLoading'
@ -135,7 +134,7 @@ export default class Database {
// clear references to IDB, e.g. during a close event
_clear () {
log('_clear database', this._dbName)
console.log('_clear database', this._dbName)
// We don't need to call removeEventListener or remove the manual "close" listeners.
// The memory leak tests prove this is unnecessary. It's because:
// 1) IDBDatabases that can no longer fire "close" automatically have listeners GCed

View File

@ -1,7 +1,6 @@
import { getETag, getETagAndData } from './utils/ajax'
import { jsonChecksum } from './utils/jsonChecksum'
import { hasData, loadData } from './idbInterface'
import { log } from '../shared/log'
export async function checkForUpdates (db, dataSource) {
// just do a simple HEAD request first to see if the eTags match
@ -16,9 +15,9 @@ export async function checkForUpdates (db, dataSource) {
}
}
if (await hasData(db, dataSource, eTag)) {
log('Database already populated')
console.log('Database already populated')
} else {
log('Database update available')
console.log('Database update available')
if (!emojiData) {
const eTagAndData = await getETagAndData(dataSource)
emojiData = eTagAndData[1]

View File

@ -1,6 +1,5 @@
import { initialMigration } from './migrations'
import { DB_VERSION_INITIAL, DB_VERSION_CURRENT } from './constants'
import { mark, stop } from '../shared/marks'
const openReqs = {}
const databaseCache = {}
@ -16,7 +15,7 @@ function handleOpenOrDeleteReq (resolve, reject, req) {
}
async function createDatabase (dbName) {
mark('createDatabase')
performance.mark('createDatabase')
const db = await new Promise((resolve, reject) => {
const req = indexedDB.open(dbName, DB_VERSION_CURRENT)
openReqs[dbName] = req
@ -38,7 +37,7 @@ async function createDatabase (dbName) {
// Unfortunately cannot test in fakeIndexedDB: https://github.com/dumbmatter/fakeIndexedDB/issues/50
/* istanbul ignore next */
db.onclose = () => closeDatabase(dbName)
stop('createDatabase')
performance.measure('createDatabase', 'createDatabase')
return db
}

View File

@ -7,7 +7,6 @@ import {
STORE_KEYVALUE
} from './constants'
import { transformEmojiData } from './utils/transformEmojiData'
import { mark, stop } from '../shared/marks'
import { extractTokens } from './utils/extractTokens'
import { getAllIDB, getAllKeysIDB, getIDB } from './idbUtil'
import { findCommonMembers } from './utils/findCommonMembers'
@ -62,7 +61,7 @@ async function doFullDatabaseScanForSingleResult (db, predicate) {
}
export async function loadData (db, emojiData, url, eTag) {
mark('loadData')
performance.mark('loadData')
try {
const transformedData = transformEmojiData(emojiData)
await dbPromise(db, [STORE_EMOJI, STORE_KEYVALUE], MODE_READWRITE, ([emojiStore, metaStore]) => {
@ -92,7 +91,7 @@ export async function loadData (db, emojiData, url, eTag) {
}
metaStore.put(eTag, KEY_ETAG)
metaStore.put(url, KEY_URL)
mark('commitAllData')
performance.mark('commitAllData')
}
getIDB(metaStore, KEY_ETAG, result => {
@ -110,9 +109,9 @@ export async function loadData (db, emojiData, url, eTag) {
checkFetched()
})
})
stop('commitAllData')
performance.measure('commitAllData', 'commitAllData')
} finally {
stop('loadData')
performance.measure('loadData', 'loadData')
}
}

View File

@ -1,6 +1,5 @@
import { warnETag } from './warnETag'
import { assertEmojiData } from './assertEmojiData'
import { mark, stop } from '../../shared/marks'
function assertStatus (response, dataSource) {
if (Math.floor(response.status / 100) !== 2) {
@ -9,23 +8,23 @@ function assertStatus (response, dataSource) {
}
export async function getETag (dataSource) {
mark('getETag')
performance.mark('getETag')
const response = await fetch(dataSource, { method: 'HEAD' })
assertStatus(response, dataSource)
const eTag = response.headers.get('etag')
warnETag(eTag)
stop('getETag')
performance.measure('getETag', 'getETag')
return eTag
}
export async function getETagAndData (dataSource) {
mark('getETagAndData')
performance.mark('getETagAndData')
const response = await fetch(dataSource)
assertStatus(response, dataSource)
const eTag = response.headers.get('etag')
warnETag(eTag)
const emojiData = await response.json()
assertEmojiData(emojiData)
stop('getETagAndData')
performance.measure('getETagAndData', 'getETagAndData')
return [eTag, emojiData]
}

View File

@ -1,15 +1,14 @@
import { binaryStringToArrayBuffer, arrayBufferToBinaryString } from 'blob-util'
import { mark, stop } from '../../shared/marks'
// generate a checksum based on the stringified JSON
export async function jsonChecksum (object) {
mark('jsonChecksum')
performance.mark('jsonChecksum')
const inString = JSON.stringify(object)
const inBuffer = binaryStringToArrayBuffer(inString)
// this does not need to be cryptographically secure, SHA-1 is fine
const outBuffer = await crypto.subtle.digest('SHA-1', inBuffer)
const outBinString = arrayBufferToBinaryString(outBuffer)
const res = btoa(outBinString)
stop('jsonChecksum')
performance.measure('jsonChecksum', 'jsonChecksum')
return res
}

View File

@ -1,10 +1,9 @@
import { mark, stop } from '../../shared/marks'
import { extractTokens } from './extractTokens'
import { normalizeTokens } from './normalizeTokens'
// Transform emoji data for storage in IDB
export function transformEmojiData (emojiData) {
mark('transformEmojiData')
performance.mark('transformEmojiData')
const res = emojiData.map(({ annotation, emoticon, group, order, shortcodes, skins, tags, emoji, version }) => {
const tokens = [...new Set(
normalizeTokens([
@ -41,6 +40,6 @@ export function transformEmojiData (emojiData) {
}
return res
})
stop('transformEmojiData')
performance.measure('transformEmojiData', 'transformEmojiData')
return res
}

View File

@ -1,7 +1,6 @@
import { warn } from '../../shared/log'
export function warnETag (eTag) {
if (!eTag) {
warn('emoji-picker-element is more efficient if the dataSource server exposes an ETag header.')
console.warn('emoji-picker-element is more efficient if the dataSource server exposes an ETag header.')
}
}

View File

@ -1,10 +1,8 @@
import SveltePicker from './components/Picker/Picker.svelte'
import { mark } from '../shared/marks'
import { log } from '../shared/log'
export default class Picker extends SveltePicker {
constructor (props) {
mark('initialLoad')
performance.mark('initialLoad')
// Make the API simpler, directly pass in the props
super({ props })
}
@ -12,7 +10,7 @@ export default class Picker extends SveltePicker {
disconnectedCallback () {
// Have to explicitly destroy the component to avoid memory leaks.
// See https://github.com/sveltejs/svelte/issues/1152
log('disconnectedCallback')
console.log('disconnectedCallback')
this.$destroy()
}

View File

@ -8,7 +8,6 @@ import { MIN_SEARCH_TEXT_LENGTH, NUM_SKIN_TONES } from '../../../shared/constant
import { requestIdleCallback } from '../../utils/requestIdleCallback'
import { hasZwj } from '../../utils/hasZwj'
import { emojiSupportLevelPromise, supportedZwjEmojis } from '../../utils/emojiSupport'
import { logError, log } from '../../../shared/log'
import { applySkinTone } from '../../utils/applySkinTone'
import { halt } from '../../utils/halt'
import { incrementOrDecrement } from '../../utils/incrementOrDecrement'
@ -23,7 +22,6 @@ import { summarizeEmojisForUI } from '../../utils/summarizeEmojisForUI'
import * as widthCalculator from '../../utils/widthCalculator'
import { checkZwjSupport } from '../../utils/checkZwjSupport'
import { requestPostAnimationFrame } from '../../utils/requestPostAnimationFrame'
import { stop } from '../../../shared/marks'
import { onMount, onDestroy, tick } from 'svelte'
import { requestAnimationFrame } from '../../utils/requestAnimationFrame'
import { uniq } from '../../../shared/uniq'
@ -128,7 +126,7 @@ $: {
await database.ready()
databaseLoaded = true // eslint-disable-line no-unused-vars
} catch (err) {
logError(err)
console.error(err)
message = i18n.networkErrorMessage
} finally {
clearTimeout(timeoutHandle)
@ -150,24 +148,24 @@ $: {
// See https://github.com/sveltejs/svelte/pull/4527
onMount(async () => {
await tick()
log('props ready: setting locale and dataSource to default')
console.log('props ready: setting locale and dataSource to default')
locale = locale || DEFAULT_LOCALE
dataSource = dataSource || DEFAULT_DATA_SOURCE
})
$: {
if (locale && dataSource && (!database || (database.locale !== locale && database.dataSource !== dataSource))) {
log('creating database', { locale, dataSource })
console.log('creating database', { locale, dataSource })
database = new Database({ dataSource, locale })
}
}
onDestroy(async () => {
if (database) {
log('closing database')
console.log('closing database')
try {
await database.close()
} catch (err) {
logError(err) // only happens if the database failed to load in the first place, so we don't care
console.error(err) // only happens if the database failed to load in the first place, so we don't care
}
}
})
@ -190,7 +188,7 @@ $: pickerStyle = `
$: {
if (customEmoji && database) {
log('updating custom emoji')
console.log('updating custom emoji')
database.customEmoji = customEmoji
}
}
@ -239,7 +237,7 @@ $: {
$: {
async function updateFavorites () {
log('updateFavorites')
console.log('updateFavorites')
const dbFavorites = await database.getTopFavoriteEmoji(numColumns)
const favorites = await summarizeEmojis(uniqBy([
...dbFavorites,
@ -314,7 +312,7 @@ $: {
$: {
async function updateEmojis () {
log('updateEmojis')
console.log('updateEmojis')
if (!databaseLoaded) {
currentEmojis = []
searchMode = false
@ -378,7 +376,7 @@ async function summarizeEmojis (emojis) {
}
async function getEmojisByGroup (group) {
log('getEmojiByGroup', group)
console.log('getEmojiByGroup', group)
if (typeof group === 'undefined') {
return []
}
@ -397,7 +395,7 @@ $: {
if (process.env.NODE_ENV !== 'production' || process.env.PERF) {
if (currentEmojis.length && currentFavorites.length && initialLoad) {
initialLoad = false
requestPostAnimationFrame(() => stop('initialLoad'))
requestPostAnimationFrame(() => performance.measure('initialLoad', 'initialLoad'))
}
}
}

View File

@ -1,12 +1,10 @@
import { mark, stop } from '../../shared/marks'
import { calculateTextWidth } from './calculateTextWidth'
import { supportedZwjEmojis } from './emojiSupport'
import { log } from '../../shared/log'
let baselineEmojiWidth
export function checkZwjSupport (zwjEmojisToCheck, baselineEmoji, emojiToDomNode) {
mark('checkZwjSupport')
performance.mark('checkZwjSupport')
for (const emoji of zwjEmojisToCheck) {
const domNode = emojiToDomNode(emoji)
const emojiWidth = calculateTextWidth(domNode)
@ -21,10 +19,10 @@ export function checkZwjSupport (zwjEmojisToCheck, baselineEmoji, emojiToDomNode
supportedZwjEmojis.set(emoji.unicode, supported)
/* istanbul ignore next */
if (!supported) {
log('Filtered unsupported emoji', emoji.unicode, emojiWidth, baselineEmojiWidth)
console.log('Filtered unsupported emoji', emoji.unicode, emojiWidth, baselineEmojiWidth)
} else if (emojiWidth !== baselineEmojiWidth) {
log('Allowed borderline emoji', emoji.unicode, emojiWidth, baselineEmojiWidth)
console.log('Allowed borderline emoji', emoji.unicode, emojiWidth, baselineEmojiWidth)
}
}
stop('checkZwjSupport')
performance.measure('checkZwjSupport', 'checkZwjSupport')
}

View File

@ -1,11 +1,10 @@
// rather than check every emoji ever, which would be expensive, just check some representatives from the
// different emoji releases to determine what the font supports
import { mark, stop } from '../../shared/marks'
import { versionsAndTestEmoji } from '../../../bin/versionsAndTestEmoji'
import { testColorEmojiSupported } from './testColorEmojiSupported'
export function determineEmojiSupportLevel () {
mark('determineEmojiSupportLevel')
performance.mark('determineEmojiSupportLevel')
let res
for (const [emoji, version] of Object.entries(versionsAndTestEmoji)) {
/* istanbul ignore else */
@ -15,6 +14,6 @@ export function determineEmojiSupportLevel () {
break
}
}
stop('determineEmojiSupportLevel')
performance.measure('determineEmojiSupportLevel', 'determineEmojiSupportLevel')
return res
}

View File

@ -1,5 +1,4 @@
import { determineEmojiSupportLevel } from './determineEmojiSupportLevel'
import { log } from '../../shared/log'
import { requestIdleCallback } from './requestIdleCallback'
// Check which emojis we know for sure aren't supported, based on Unicode version level
export const emojiSupportLevelPromise = new Promise(resolve => (
@ -14,6 +13,6 @@ export const supportedZwjEmojis = new Map()
/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
emojiSupportLevelPromise.then(emojiSupportLevel => {
log('emoji support level', emojiSupportLevel)
console.log('emoji support level', emojiSupportLevel)
})
}

View File

@ -1,22 +0,0 @@
// @rollup/plugin-strip doesn't strip console.logs properly
export function log () {
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
console.log(...arguments)
}
}
export function warn () {
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'test') {
console.warn(...arguments)
}
}
export function logError () {
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'test') {
console.error(...arguments)
}
}

View File

@ -1,18 +0,0 @@
// @rollup/plugin-strip doesn't properly strip performance.mark/measure
/* istanbul ignore next */
const hasPerfMarks = typeof performance !== 'undefined' && performance.mark && performance.measure
export function mark (str) {
/* istanbul ignore next */
if ((process.env.NODE_ENV !== 'production' || process.env.PERF) && hasPerfMarks) {
performance.mark(str)
}
}
export function stop (str) {
/* istanbul ignore next */
if ((process.env.NODE_ENV !== 'production' || process.env.PERF) && hasPerfMarks) {
performance.measure(str, str)
}
}

View File

@ -24,6 +24,9 @@ describe('attributes tests', () => {
expect(picker.dataSource).toEqual(FR_EMOJI)
expect(picker.getAttribute('locale')).toEqual('fr')
expect(picker.getAttribute('data-source')).toEqual(FR_EMOJI)
document.body.removeChild(picker)
await tick(20)
})
test('can set skintone emoji using an attribute', async () => {
@ -43,5 +46,8 @@ describe('attributes tests', () => {
expect(getByRole(picker.shadowRoot, 'button', { name: /Choose a skin tone/ }).innerHTML)
.toContain('🏃')
expect(picker.skinToneEmoji).toEqual('🏃')
document.body.removeChild(picker)
await tick(20)
})
})

View File

@ -30,5 +30,8 @@ describe('Custom emojis tests', () => {
await tick(50)
await waitFor(() => expect(getByRole(container, 'menuitem', { name: 'monkey' })).toBeVisible())
document.body.removeChild(picker)
await tick(20)
})
})

View File

@ -1540,6 +1540,15 @@
"@rollup/pluginutils" "^3.1.0"
magic-string "^0.25.7"
"@rollup/plugin-strip@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@rollup/plugin-strip/-/plugin-strip-2.0.1.tgz#276e7789a33ae0b10bc8522a20f187d8a6b6b550"
integrity sha512-+JJInHt/90Ta/ofCH+YHrI6nyDKe9jVzwBkmnakjDUMD+2QUTPHy60jep+kaMm4ARKWavtfmPbQp7e+xxAHU7g==
dependencies:
"@rollup/pluginutils" "^3.1.0"
estree-walker "^2.0.1"
magic-string "^0.25.7"
"@rollup/pluginutils@^3.0.8":
version "3.0.10"
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.0.10.tgz#a659b9025920378494cd8f8c59fbf9b3a50d5f12"