As I set out to create a basic website, I opted to utilize webpack for packaging. TypeScript and SASS were my choice of tools due to their familiarity from daily use.
Following the documentation at https://webpack.js.org, I encountered issues with loaders like awesome-typescript-loader
and ts-loader
when incorporating ES6/TypeScript features in my code, such as type definitions and classes.
Transpiling my main.ts
file resulted in the following error:
ERROR in ./src/app/main.ts
Module parse failed: Unexpected token (4:17)
You may need an appropriate loader to handle this file type.
| import { Slider } from './components/slider/slider.component';
|
| const contactForm: ContactForm = new ContactForm('#contact-form');
|
| const slider: Slider = new Slider('#slider-container', '.slide');
The contents of my main.ts
:
import { ContactForm } from './components/contact-form/contact-form.component';
import { Slider } from './components/slider/slider.component';
const contactForm: ContactForm = new ContactForm('#contact-form');
const slider = new Slider('#slider-container', '.slide');
Presenting my slider.component.ts
:
export class Slider {
private container: HTMLElement;
private slides: HTMLElement[];
constructor(containerSelector: string, slidesSelector: string) {
this.container = document.querySelector(containerSelector);
this.slides = Array.from(document.querySelectorAll(slidesSelector));
const containerWidth: number = this.slides
.map(slide => slide.offsetWidth)
.reduce((sum, offsetWidth) => sum + offsetWidth, 0);
this.container.style.width = `${containerWidth}px`;
}
}
Eliminating the types allowed successful transpilation of main.ts
, but led to errors such as:
ERROR in ./src/app/components/contact-form/contact-form.component.ts
Module parse failed: Unexpected token (3:10)
You may need an appropriate loader to handle this file type.
| export class ContactForm {
|
| private form: any;
|
| constructor(formSelector: string) {
@ ./src/app/main.ts 1:0-79
ERROR in ./src/app/components/slider/slider.component.ts
Module parse failed: Unexpected token (3:10)
You may need an appropriate loader to handle this file type.
| export class Slider {
|
| private container: HTMLElement;
| private slides: HTMLElement[];
|
@ ./src/app/main.ts 2:0-62
Here is my webpack.common.js
:
const path = require("path");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
module.exports = {
devtool: "source-map",
entry: {
scripts: "./src/app/main.ts",
styles: "./src/app/styles.scss",
},
resolve: {
extensions: [".js", ".ts", ".tsx", ".scss"],
symlinks: false,
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: "/\.tsx?$/",
use: {
loader: "ts-loader",
options: {
configFile: "./tsconfig.json",
happyPackMode: true,
transpileOnly: true,
},
},
exclude: /node_modules/,
},
{
test: /\.scss$/,
use: [
{
loader: "style-loader",
options: {
insertAt: "top",
},
},
{
loader: "css-loader",
options: { sourceMap: true },
},
{
loader: "sass-loader",
options: { sourceMap: true },
},
],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [ "file-loader" ],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [ "file-loader" ],
},
],
},
plugins: [
new CleanWebpackPlugin(["dist"]),
new HtmlWebpackPlugin({
template: "src/app/index.html",
}),
new ForkTsCheckerWebpackPlugin({
checkSyntaticErrors: true,
}),
],
};
This is my webpack.dev.js
:
const webpack = require("webpack");
const merge = require("webpack-merge");
const common = require("./webpack.common.js");
module.exports = merge(common, {
devServer: {
contentBase: "./dist",
clientLogLevel: "none",
port: 3000,
hot: true,
overlay: true
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
],
});
Configurations found in tsconfig.json
:
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist",
"noImplicitAny": false,
"module": "commonjs",
"target": "es5",
"baseUrl": "src",
"allowJs": true,
"sourceMap": true,
"moduleResolution": "node",
"lib": [
"es2016",
"dom"
],
"declaration": false,
"typeRoots": [
"node_modules/@types"
]
}
}
Lastly, here's my package.json
:
...
"scripts": {
"start": "webpack-dev-server --config webpack.dev.js",
"build": "webpack --config webpack.prod.js"
},
"dependencies": {
"clean-webpack-plugin": "^0.1.17",
"css-loader": "^0.28.7",
"file-loader": "^1.1.5",
"fork-ts-checker-webpack-plugin": "^0.2.9",
"html-webpack-plugin": "^2.30.1",
"node-sass": "^4.7.2",
"sass-loader": "^6.0.6",
"style-loader": "^0.19.0",
"ts-loader": "^3.2.0",
"tslint": "^5.8.0",
"typescript": "^2.6.2",
"uglifyjs-webpack-plugin": "^1.1.1",
"webpack": "^3.8.1",
"webpack-dev-server": "^2.9.5",
"webpack-merge": "^4.1.1"
},
"devDependencies": {
"@types/node": "^8.0.54"
}