Skip to content
Snippets Groups Projects
Commit f06fa11f authored by squidfunk's avatar squidfunk
Browse files

Translated webpack config to TypeScript

parent 2a48e17d
Branches
Tags
No related merge requests found
Showing
with 1998 additions and 83 deletions
......@@ -33,7 +33,7 @@ node_modules:
# -----------------------------------------------------------------------------
# Build theme for distribution with Webpack
material: $(shell find src) .babelrc webpack.config.js
material: $(shell find src) .babelrc webpack.config.ts
$(shell npm bin)/webpack --env.prod
# -----------------------------------------------------------------------------
......
!function(n,r){for(var t in r)n[t]=r[t]}(window,function(n){function r(e){if(t[e])return t[e].exports;var o=t[e]={i:e,l:!1,exports:{}};return n[e].call(o.exports,o,o.exports,r),o.l=!0,o.exports}var t={};return r.m=n,r.c=t,r.d=function(n,t,e){r.o(n,t)||Object.defineProperty(n,t,{configurable:!1,enumerable:!0,get:e})},r.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(t,"a",t),t},r.o=function(n,r){return Object.prototype.hasOwnProperty.call(n,r)},r.p="",r(r.s=53)}({53:function(n,r,t){"use strict";console.log("it works!")}}));
\ No newline at end of file
......@@ -54,7 +54,7 @@
{% endif %}
{% endblock %}
{% block libs %}
<script src="{{ base_url }}/assets/javascripts/modernizr.1aa3b519.js"></script>
<script src="{{ base_url }}/assets/javascripts/modernizr.9178d902.js"></script>
{% endblock %}
{% block fonts %}
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
......@@ -173,7 +173,8 @@
{% endblock %}
</div>
{% block scripts %}
<script src="{{ base_url }}/assets/javascripts/application.e437c97b.js"></script>
<script src="{{ base_url }}/assets/javascripts/application.fa460457.js"></script>
<script src="{{ base_url }}/assets/javascripts/index.aa3f3817.js"></script>
{% if lang.t("search.language") != "en" %}
{% set languages = lang.t("search.language").split(",") %}
{% if languages | length and languages[0] != "" %}
......
This diff is collapsed.
......@@ -31,6 +31,10 @@
},
"dependencies": {},
"devDependencies": {
"@types/html-minifier": "^3.5.1",
"@types/node": "^9.4.6",
"@types/uglify-js": "^2.6.30",
"@types/webpack": "^3.8.8",
"autoprefixer": "^8.0.0",
"babel-cli": "^6.26.0",
"babel-core": "^6.25.0",
......@@ -72,6 +76,10 @@
"stylelint-config-standard": "^18.0.0",
"stylelint-order": "^0.8.0",
"stylelint-scss": "^2.0.0",
"ts-loader": "^3.5.0",
"ts-node": "^5.0.0",
"tslint": "^5.9.1",
"typescript": "^2.7.2",
"uglify-js": "^3.1.10",
"unfetch": "^3.0.0",
"webpack": "^3.4.1",
......
console.log("it works!")
......@@ -314,6 +314,7 @@
<!-- Theme-related JavaScript -->
{% block scripts %}
<script src="{{ base_url }}/assets/javascripts/application.js"></script>
<script src="{{ base_url }}/assets/javascripts/index.js"></script>
<!-- Load additional languages for search -->
{% if lang.t("search.language") != "en" %}
......
{
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"alwaysStrict": true,
"baseUrl": ".",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"dom",
"es6",
"esnext"
],
"module": "commonjs",
"moduleResolution": "node",
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"preserveConstEnums": true,
"removeComments": true,
"strictFunctionTypes": true,
"stripInternal": true,
"target": "es6"
},
"exclude": [
"node_modules"
]
}
{
"extends": [
"tslint:latest"
],
"rules": {
"arrow-parens": [
true,
"ban-single-arg-parens"
],
"class-name": true,
"comment-format": [
true,
"check-space"
],
"curly": [
true,
"as-needed"
],
"indent": [
true,
"spaces"
],
"interface-name": false,
"jsdoc-format": true,
"no-implicit-dependencies": false,
"no-internal-module": true,
"no-null-keyword": true,
"no-submodule-imports": false,
"no-trailing-whitespace": true,
"no-var-keyword": true,
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-whitespace"
],
"prefer-const": true,
"quotemark": [
true,
"double",
"avoid-escape"
],
"semicolon": [
true,
"never"
],
"trailing-comma": [
true,
{
"multiline": {
"objects": "never",
"arrays": "never",
"functions": "never",
"typeLiterals": "never"
},
"esSpecCompliant": true
}
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "onespace",
"index-signature": "onespace",
"parameter": "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace"
}
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-module",
"check-separator",
"check-type"
]
}
}
/*
* Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
declare module "copy-webpack-plugin" {
import { Plugin } from "webpack"
class CopyPlugin extends Plugin {
constructor(options: any)
}
export = CopyPlugin
}
/*
* Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
declare module "event-hooks-webpack-plugin" {
import { Plugin } from "webpack"
class EventHooksPlugin extends Plugin {
constructor(options: any)
}
export = EventHooksPlugin
}
/*
* Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
declare module "extract-text-webpack-plugin" {
import { Plugin } from "webpack"
class ExtractTextPlugin extends Plugin {
constructor(options: any)
public extract(options: any): any
}
export = ExtractTextPlugin
}
/*
* Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
declare module "imagemin-webpack-plugin" {
import { Plugin } from "webpack"
class ImageminPlugin extends Plugin {
constructor(options: any)
}
export default ImageminPlugin
}
/*
* Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
declare module "webpack-manifest-plugin" {
import { Plugin } from "webpack"
class ManifestPlugin extends Plugin {
constructor(options: any)
}
export = ManifestPlugin
}
......@@ -20,28 +20,40 @@
* IN THE SOFTWARE.
*/
const fs = require("fs")
const path = require("path")
const html = require("html-minifier")
const uglify = require("uglify-js")
const webpack = require("webpack")
import * as fs from "fs"
import * as html from "html-minifier"
import * as path from "path"
import * as uglify from "uglify-js"
import {
Configuration,
NewModule,
optimize,
ProvidePlugin
} from "webpack"
/* ----------------------------------------------------------------------------
* Plugins
* ------------------------------------------------------------------------- */
const CopyPlugin = require("copy-webpack-plugin")
const EventHooksPlugin = require("event-hooks-webpack-plugin")
const ExtractTextPlugin = require("extract-text-webpack-plugin")
const ImageminPlugin = require("imagemin-webpack-plugin").default
const ManifestPlugin = require("webpack-manifest-plugin")
import CopyPlugin = require("copy-webpack-plugin")
import EventHooksPlugin = require("event-hooks-webpack-plugin")
import ExtractTextPlugin = require("extract-text-webpack-plugin")
import ImageminPlugin from "imagemin-webpack-plugin"
import ManifestPlugin = require("webpack-manifest-plugin")
/* Webpack plugins */
const {
CommonsChunkPlugin,
UglifyJsPlugin
} = optimize
/* ----------------------------------------------------------------------------
* Configuration
* ------------------------------------------------------------------------- */
module.exports = env => {
const config = {
export default (env?: { prod?: boolean }) => {
const config: Configuration = {
/* Entrypoints */
entry: {
......@@ -51,9 +63,14 @@ module.exports = env => {
__dirname, "src/assets/javascripts/modernizr.js"
),
/* Application */
/* Old application */
"assets/javascripts/application": path.resolve(
__dirname, "src/assets/javascripts/application.js"
),
/* New application */
"assets/javascripts/index": path.resolve(
__dirname, "src/assets/javascripts/index.ts"
)
},
......@@ -61,6 +78,13 @@ module.exports = env => {
module: {
rules: [
/* TypeScript */
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /\/node_modules\//
},
/* Babel ES6 transformations */
{
test: /\.jsx?$/,
......@@ -87,8 +111,7 @@ module.exports = env => {
/* Output */
output: {
path: path.resolve(__dirname, "material"),
filename: `[name]${env && env.prod ? ".[chunkhash]" : ""}.js`,
hashDigestLength: 8,
filename: `[name]${env && env.prod ? ".[chunkhash:8]" : ""}.js`,
libraryTarget: "window"
},
......@@ -96,13 +119,13 @@ module.exports = env => {
plugins: [
/* Combine all dependencies into a single file */
new webpack.optimize.CommonsChunkPlugin({
new CommonsChunkPlugin({
name: "src/assets/javascripts/modernizr.js",
chunks: [".modernizr-autorc"]
}),
/* Provide JSX helper */
new webpack.ProvidePlugin({
new ProvidePlugin({
JSX: path.resolve(__dirname, "src/assets/javascripts/providers/jsx.js")
}),
......@@ -117,7 +140,7 @@ module.exports = env => {
context: path.resolve(__dirname, "node_modules/lunr-languages"),
to: "assets/javascripts/lunr",
from: "*.js",
transform: content => {
transform: (content: any) => {
return uglify.minify(content.toString()).code
}
},
......@@ -138,7 +161,7 @@ module.exports = env => {
{
context: "src",
from: "**/*.html",
transform: content => {
transform: (content: string) => {
const metadata = require(path.resolve(__dirname, "package.json"))
return html.minify(content.toString(), {
collapseBooleanAttributes: true,
......@@ -178,11 +201,11 @@ module.exports = env => {
macOS when starting for the first time. This is a quick fix until
this issue is resolved. See: http://bit.ly/2AsizEn */
new EventHooksPlugin({
"watch-run": (compiler, cb) => {
"watch-run": (compiler: any, cb: () => {}) => {
compiler.startTime += 10000
cb()
},
"done": stats => {
"done": (stats: any) => {
stats.startTime -= 10000
}
})
......@@ -200,7 +223,7 @@ module.exports = env => {
},
/* Sourcemaps */
devtool: !env || env.prod ? "inline-source-map" : ""
devtool: !env || env.prod ? "inline-source-map" : undefined
}
/* Compile stylesheets */
......@@ -215,8 +238,8 @@ module.exports = env => {
)}.css`)
/* Register plugin */
config.plugins.push(plugin)
config.module.rules.push({
config.plugins.push(plugin);
(config.module as NewModule).rules.push({
test: new RegExp(`${stylesheet}$`),
use: plugin.extract({
use: [
......@@ -256,11 +279,12 @@ module.exports = env => {
}
/* Production compilation */
if (env && env.prod) {
if (env && env.prod)
config.plugins.push(
/* Uglify sources */
new webpack.optimize.UglifyJsPlugin({
new UglifyJsPlugin({
comments: false,
compress: {
warnings: false,
screw_ie8: true, // eslint-disable-line camelcase
......@@ -272,16 +296,13 @@ module.exports = env => {
evaluate: true,
if_return: true, // eslint-disable-line camelcase
join_vars: true // eslint-disable-line camelcase
},
output: {
comments: false
}
}),
/* Minify images */
new ImageminPlugin({
test: /\.(ico|png|svg)$/i,
svgo: null
svgo: null // tslint:disable-line no-null-keyword
// Hack: Temporarily disabled, as SVGO removes the viewbox property
// and setting the plugin to false doesn't have any effect.
// {
......@@ -299,7 +320,7 @@ module.exports = env => {
/* This is an ugly workaround for the fact that the manifest plugin
doesn't handle multiple chunks. See http://bit.ly/2BbfER9 */
map(file) {
map(file: any) {
file.name = file.path.replace(/\.[a-z0-9].+\.(css|js|svg)/i, ".$1")
return file
}
......@@ -307,7 +328,7 @@ module.exports = env => {
/* Apply manifest */
new EventHooksPlugin({
"after-emit": (compilation, cb) => {
"after-emit": (compilation: any, cb: () => {}) => {
const manifest = require(path.resolve("material/manifest.json"))
Object.keys(compilation.assets).forEach(name => {
if (name.match(/\.html/)) {
......@@ -322,7 +343,6 @@ module.exports = env => {
}
})
)
}
/* Oh my god, that was a hell of a setup */
return config
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment