sequelize-browser
v6.1.3
Published
Sequelize build that runs in a web browser
Downloads
14
Maintainers
Readme
sequelize-browser
A build of Sequelize that runs in a web browser.
Install
npm install sequelize-browser --save
Use
There're two ways of using this package:
- The most simple way would be using the default build that was created from the latest version of Sequelize at the time of publishing this package.
- The "advanced" way would be creating a custom build for a particular version of Sequelize.
Default Build
A pre-made build of sequelize@6
is available as part of this package.
The files are:
sequelize.js
— A non-"minified" "ES6" version of the build. It can beimport
ed when using a bundler such as Webpack.sequelize.cjs
— A non-"minified" "CommonJS" version of the build. It can berequire()
d when using a bundler such as Webpack.sequelize.script.js
— A "minified" "bundled" build for including it on a web page via a<script/>
tag. Sequelize will be available asSequelize
global variable.
Use it either way:
import Sequelize from 'sequelize-browser'
const Sequelize = require('sequelize-browser')
<script src="https://unpkg.com/[email protected]/sequelize.script.js"></script>
<script>
console.log(Sequelize)
</script>
Custom Build
To create a custom build from a particular version of Sequelize, first install that particular version of Sequelize:
npm install [email protected]
After that, either use the command-line way of running the build via npx
command or use a programmatic way of running the build via sequelize-browser/build
export.
Command Line
First, install npx
if it's not already installed in your system:
npm install -g npx
Then, run the build command:
npx sequelize-browser \
--input ./node_modules/sequelize \
--output ./output/sequelize.js \
--dialects sqlite,mysql
--format iife \
--minify true
Programmatic
import build from 'sequelize-browser/build'
await build({
// Path to the installed version of Sequelize.
input: './node_modules/sequelize',
// Path to the output file.
output: './output/sequelize.js',
// Supported "dialects".
dialects: ['sqlite'],
// * "esm" — For including the resulting file via `import`.
// * "cjs" — For including the resulting file via `require()`.
// * "iife" — For including the resulting file directly via a "<script/>" tag on a page.
format: 'iife',
// Whether it should "minify" the code.
minify: true
})
Databases
The following databases have been tested and appear to be working:
- SQLite — with
sqlite
"dialect" andsql.js-as-sqlite3
package as adialectModule
parameter value.
Node.js
import Sequelize from 'sequelize'
import sqlJsAsSqlite3 from 'sql.js-as-sqlite3'
const sequelize = new Sequelize('sqlite://:memory:', {
dialectModule: sqlJsAsSqlite3
})
Browser (with bundler)
import Sequelize from 'sequelize'
import sqlJsAsSqlite3 from 'sql.js-as-sqlite3'
import initSqlJs from 'sql.js'
sqlJsAsSqlite3.configure({
// `sql.js` package default export.
initSqlJs,
// Base URL for `sql.js` to get the `*.wasm` files like `sql-wasm-debug.wasm`.
// The version of the `*.wasm` files must match the version of the `sql.js` package.
// Must end with a "/".
wasmFileBaseUrl: 'https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.2/'
})
const sequelize = new Sequelize('sqlite://:memory:', {
dialectModule: sqlJsAsSqlite3
})
Browser (no bundler)
One can use any npm CDN service, e.g. unpkg.com or jsdelivr.net
<script src="https://unpkg.com/[email protected]/sequelize.script.js"></script>
<script src="https://unpkg.com/[email protected]/bundle/sql.js-as-sqlite3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.2/sql-wasm.min.js"></script>
<script>
// Base URL for `sql.js` to get the `*.wasm` files like `sql-wasm-debug.wasm`.
// The version of the `*.wasm` files must match the version of `sql.js`.
// Must end with a "/".
SQL_JS_WASM_FILE_BASE_URL = 'https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.2/'
</script>
<script>
const sequelize = new Sequelize('sqlite://:memory:', {
dialectModule: sqlJsAsSqlite3
})
</script>
Limitations
Transactions
(Advanced Feature) When creating "managed" transactions via sequelize.transaction(options, callback)
, it utilizes the "CLS" (Continuation Local Storage) feature of Node.js to automatically (or rather "automagically") select that transaction for any queries dispatched from the callback
.
await sequelize.transaction(async () => {
// This `.create()` call will be executed inside the transaction.
const user = await User.create({
firstName: 'Abraham',
lastName: 'Lincoln'
});
});
When running in a web browser, that magic of Node.js is not available, so a developer will have to explicitly specify the transaction for queries dispatched from the callback
.
await sequelize.transaction(async t => {
const user = await User.create({
firstName: 'Abraham',
lastName: 'Lincoln'
}, { transaction: t });
});
Validator
By default, Sequelize supports specifying "validators" from validator.js
library on a model field.
sequelize.define('modelName', {
fieldName: {
type: DataTypes.STRING,
validate: {
isPostalCode: true, // Implicitly calls `isPostalCode(value)` function from `validator.js` library.
isUppercase: true // Implicitly calls `isUppercase(value)` function from `validator.js` library.
}
}
})
However, while being convenient, including the whole validator.js
package in the bundle just to support that feature increases its size by about 100 KB
, which looks like an overkill provided that most people don't even use this feature, or maybe only use a few of the "validators" from the (long) list.
So to reduce the overall bundle size, and to decouple sequelize
itself from validator.js
package, the feature was removed. When attempting to call a certain function of validator.js
, it will throw an error like:
isPostalCode
function fromvalidator
package is not included in a browser version ofsequelize
. To fix this, import theisPostalCode
function fromvalidator
package manually and then either (a) use it in a field'svalidate
or (b) set it on theSequelize.Validator
object.
As the error message suggests, there're two simple ways to fix it.
The first way would be import
ing the relevant "validator" functions from validator.js
and then using them in the validate
map of a model field.
import isPostalCode from 'validator/lib/isPostalCode'
import isUppercase from 'validator/lib/isUppercase'
sequelize.define('modelName', {
fieldName: {
type: DataTypes.STRING,
validate: {
isPostalCode: value => isPostalCode(value),
isUppercase: value => isUppercase(value)
}
}
})
The second way would be import
ing the relevant "validator" functions from validator.js
and then setting them on the Sequelize.Validator
object.
import isPostalCode from 'validator/lib/isPostalCode'
import isUppercase from 'validator/lib/isUppercase'
Sequelize.Validator.isPostalCode = isPostalCode
Sequelize.Validator.isUppercase = isUppercase
Bundle Size
The bundle size is currently at about 1.5 MB
.
(resolved in
sequelize@7
code) Half of that ismoment
's timezone data. The latest code in thesequelize
repo seems to have replacedmoment
withdayjs
which means that in the next "major" release ofsequelize
the browser bundle will be much smaller.- After
sequelize@7
is published, uncommentmoment
"shim" insource/aliases.js
and rebuild the package.
- After
(resolved in
sequelize@7
code) In the current version ofsequelize
,validator
is imported as a whole instead of only the functions being used, which is about115 KB
of the bundle size. Reducing the scope of the functions imported fromvalidator
would reduce the bundle size by a tiny bit. See the discussion.- After
sequelize@7
is published, uncommentvalidator
"shim" insource/aliases.js
and rebuild the package.
- After
(resolved in
sequelize@7
code) In the current version ofsequelize
,lodash
is imported as a whole instead of only the functions being used, which is about75 KB
of the bundle size. Reducing the scope of the functions imported fromlodash
could reduce the bundle size by a tiny bit, although negligibly.- After
sequelize@7
is published, this is supposed to no longer be an issue.
- After
To get more insight on what exactly occupies which part of the bundle, use the sequelize.script.js.meta.json
file in the root of the package with a bundle analyzer:
- https://bundle-buddy.com
- https://esbuild.github.io/analyze
Sequelize
A pull request was submitted to the original sequelize
package repo, although the maintainers of the original package preferred not to include it and instead would prefer to follow a more radical approach with rewriting the entire sequelize
codebase in a more modern way, resolving any web browser incompatibilities in the process. Although I'd imagine such a large rewrite could potentially require an equally large amount of time, but at the same time this feature is more of a for-fun thing rather than some critical piece of functionality. Anyway, in the end, a decision was made to release this browser build of Sequelize as a standalone third-party package, so here it is. It also provides the commands to manually run the build from the original sequelize
package so that any developer could easily create a browser-compatible build for any version of sequelize. For reference, here's the original discussion.
GitHub
On March 9th, 2020, GitHub, Inc. silently banned my account (erasing all my repos, issues and comments, even in my employer's private repos) without any notice or explanation. Because of that, all source codes had to be promptly moved to GitLab. The GitHub repo is now only used as a backup (you can star the repo there too), and the primary repo is now the GitLab one. Issues can be reported in any repo.