EcmaScript Modules
My study notes and examples on EcmaScript/JavaScript Modules
Table of Contents
v01: Basic Example 01
cat ex/ecmascript_modules_ex01.js
## export function addTextToBody(text) {
## const div = document.createElement('div');
## div.textContent = text;
## document.body.appendChild(div);
## }
export function addTextToBody(text) { ... }
Using import
inside <script type="module">
tag:
cat ex/ecmascript_modules_ex01.html
## <!doctype html>
## <html lang="en">
## <head>
## <meta charset="utf-8">
## <title>Es Module Demo</title>
## </head>
## <body>
## <main id="js-main" class="main"></main>
## <script type="module">
## import {addTextToBody} from './ecmascript_modules_ex01.js';
## addTextToBody('Modules are pretty cool.');
## </script>
## </body>
## </html>
import {addTextToBody} from './ecmascript_modules_ex01.js';
addTextToBody('Modules are pretty cool.');
We have two options to open web page:
We can start a static web server in order to prevent CORS errors:
python3 -m http.server
Open web page:
Or we can open the web page from a static web server such as rawgit:
https://rawgit.com/mertnuhoglu/study/master/js/ex/ecmascript_modules_ex01.html
v04: Webpack Official Getting Started Tutorial
Following Webpack Getting Started Tutorial, I typed the following commands:
mkdir -p ex/ecmascript_modules_ex04
cd ex/ecmascript_modules_ex04
npm init -y
npm install webpack webpack-cli -D
mkdir src
mkdir dist
npm install --save lodash
cat ex/ecmascript_modules_ex04/src/index.html
## <!doctype html>
## <html>
## <head>
## <title>Getting Started</title>
## </head>
## <body>
## <script src="bundle.js"></script>
## </body>
## </html>
cat ex/ecmascript_modules_ex04/src/index.js
## import _ from 'lodash';
##
## function component() {
## var element = document.createElement('div');
## element.innerHTML = _.join(['Hello', 'webpack'], ' ');
## return element;
## }
## document.body.appendChild(component());
cp src/index.html dist/index.html
./node_modules/.bin/webpack src/index.js --output dist/bundle.js
Note that, here we don’t generate dist/index.html
. Instead we simply copied it from src/index.html
. Later, we will use HtmlWebpackPlugin
to generate it.
open dist/index.html
Open web page:
https://rawgit.com/mertnuhoglu/study/master/js/ex/ecmascript_modules_ex04/dist/index.html
v05: Configuration File: webpack.config.js
Now, let’s use configuration file to specify parameters of webpack:
I copied everything from ecmascript_modules_ex04
into a new folder
cp -R ex/ecmascript_modules_ex04 ex/ecmascript_modules_ex05
cat ex/ecmascript_modules_ex05/webpack.config.js
## const path = require('path');
## module.exports = {
## entry: './src/index.js',
## output: {
## filename: 'bundle.js',
## path: path.resolve(__dirname, 'dist')
## }
## }
Now, we will use configuration settings while running webpack
:
cd ex/ecmascript_modules_ex05
./node_modules/.bin/webpack --config webpack.config.js
Open web page:
https://rawgit.com/mertnuhoglu/study/master/js/ex/ecmascript_modules_ex05/dist/index.html
v06: Asset Management
Loading CSS
cp -R ex/ecmascript_modules_ex05 ex/ecmascript_modules_ex06
cd ex/ecmascript_modules_ex06
npm install --save-dev style-loader css-loader
Add style-loader
and css-loader
to webpack configuration:
cat ex/ecmascript_modules_ex06/webpack.config.js | sed -n '/module:/,/}/ p'
## module: {
## rules: [
## {
## test: /\.css$/,
## use: [
## 'style-loader',
## 'css-loader'
## ]
## },
Now, we can import
css files into the js scripts.
cat ex/ecmascript_modules_ex06/src/style.css
## .hello {
## color: blue;
## }
To use css in js:
import './style.css'; // +
...
element.classList.add('hello'); // +
cat ex/ecmascript_modules_ex06/src/index.js
## import _ from 'lodash';
## import './style.css'; // +
## import Icon from './icon.png'; // +
## import Data from './data.csv'; // +
##
## function component() {
## var element = document.createElement('div');
## element.innerHTML = _.join(['Hello', 'webpack'], ' ');
## element.classList.add('hello'); // +
## var myIcon = new Image();
## myIcon.src = Icon;
## element.appendChild(myIcon);
## console.log(Data);
## return element;
## }
## document.body.appendChild(component());
Loading Images
npm install --save-dev file-loader
Add to webpack.config.js
:
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
To load image files inside js:
import Icon from './icon.png'; // +
...
var myIcon = new Image();
myIcon.src = Icon;
element.appendChild(myIcon);
Loading Data
npm install --save-dev csv-loader
Add to webpack.config.js
:
{
test: /\.(csv|tsv)$/,
use: [
'csv-loader'
]
}
To load image files inside js:
import Data from './data.csv'; // +
...
console.log(Data);
Open web page:
https://rawgit.com/mertnuhoglu/study/master/js/ex/ecmascript_modules_ex06/dist/index.html
v07: Output Management
cp -R ex/ecmascript_modules_ex06 ex/ecmascript_modules_ex07
cd ex/ecmascript_modules_ex07
npm install --save-dev html-webpack-plugin
Add HtmlWebpackPlugin
to webpack configuration:
const HtmlWebpackPlugin = require('html-webpack-plugin');
...
plugins: [
new HtmlWebpackPlugin({
title: 'Output Management'
})
],
HtmlWebpackPlugin
generates dist/index.html
.
Cleaning up the /dist
folder
npm install --save-dev clean-webpack-plugin
Add CleanWebpackPlugin
to webpack configuration:
const CleanWebpackPlugin = require('clean-webpack-plugin');
...
plugins: [
new CleanWebpackPlugin(['dist']),
Open web page:
https://rawgit.com/mertnuhoglu/study/master/js/ex/ecmascript_modules_ex07/dist/index.html
v08: Development
Using source maps
How to track down errors? Webpack bundles source files into one bundle.js. When an error occurs how are we going to know from which origin file it comes from?
So, we will split our webpack configuration into two: one for development environment, one for production environment.
cp -R ex/ecmascript_modules_ex07 ex/ecmascript_modules_ex08
cd ex/ecmascript_modules_ex08
Add inline-source-map
to webpack configuration:
devtool: 'inline-source-map',
Watching Updates in Files
Every time we make a change in some file, we need to run npm run build
.
Let’s run this command automatically after each change.
npm install --save-dev webpack-dev-server
Update webpack.config.js
devServer: {
contentBase: './dist'
}
This setups a static web server for ./dist
directory on localhost:8080
.
Update package.json
"start": "webpack-dev-server --open",
Run npm start
Open web page: http://localhost:8080
Since these settings are for development purpose, we won’t open this page from static web server.
v09: Hot Module Replacement HMR
HMR allows any file to be updated without refresh or recompiling.
cp -R ex/ecmascript_modules_ex08 ex/ecmascript_modules_ex09
cd ex/ecmascript_modules_ex09
Enabling HMR
cp -R ex/ecmascript_modules_ex08 ex/ecmascript_modules_ex09
cd ex/ecmascript_modules_ex09
webpack.config.js
devServer: {
contentBase: './dist',
hot: true
},
...
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
Run npm start
Open web page: http://localhost:8080
v10: Using JQuery
Using jquery and its addin libraries according to the ES module rules is not as simple as it should be.
I follow the instructions given in Webpack 2, jQuery plugins and imports-loader by Stefan Ledin.
Use imports-loader
webpack plugin
cp -R ex/ecmascript_modules_ex09 ex/ecmascript_modules_ex10
cd ex/ecmascript_modules_ex10
npm install --save-dev imports-loader
npm install --save jquery
Put jquery addin library chosen.js into src/vendor
tree ex/ecmascript_modules_ex10
## ex/ecmascript_modules_ex10 [error opening dir]
##
## 0 directories, 0 files
Add imports-loader
for jquery to webpack.config.js
{
test: /vendor\/.+\.(jsx|js)$/,
use: [
'imports-loader?jQuery=jquery,$=jquery,this=>window',
]
},
Add import
statements for jquery and its plugins to index.js
import {$, jQuery} from 'jquery';
window.$ = $;
window.jQuery = jQuery;
import "./vendor/chosen.jquery.min";
Run npm start
Open web page: http://localhost:8080
Source code in https://github.com/mertnuhoglu/study/tree/master/js/ex/ecmascript_modules_ex10/
v11: Using JQuery 02
Try ProvidePlugin
I follow the instructions given in Webpack Documentation.
Use ProvidePlugin
webpack plugin
cp -R ex/ecmascript_modules_ex10 ex/ecmascript_modules_ex11
cd ex/ecmascript_modules_ex11
rm -rf node_modules
npm install --save-dev html-webpack-plugin
npm install
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
Now, we can use $
anywhere in the scripts.
Source code in https://github.com/mertnuhoglu/study/tree/master/js/ex/ecmascript_modules_ex11/