Skip to content
This repository has been archived by the owner on Jun 5, 2021. It is now read-only.

Commit

Permalink
Extract webpack config creation from compilation
Browse files Browse the repository at this point in the history
This will be useful to reuse the same config for webpack serve.

Prerequisite for #6.
  • Loading branch information
fwouts committed May 18, 2018
1 parent 19d1736 commit 201e8e4
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 166 deletions.
1 change: 1 addition & 0 deletions internal/web_bundle/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package(default_visibility = ["//internal:rules"])

exports_files([
"compile.js",
"create_webpack_config.js",
"default.index.html",
"rule.bzl",
])
179 changes: 17 additions & 162 deletions internal/web_bundle/compile.js
Original file line number Diff line number Diff line change
@@ -1,169 +1,24 @@
const child_process = require("child_process");
const fs = require("fs-extra");
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");

const [
nodePath,
scriptPath,
libBuildfilePath,
entry,
htmlTemplatePath,
target,
mode,
optionalLibrary,
splitChunksStr,
loadersNpmPackagesDir,
installedNpmPackagesDir,
compiledDir,
outputBundleDir
] = process.argv;
const [nodePath, scriptPath, webpackConfigFilePath] = process.argv;

const [libraryName, libraryTarget] = optionalLibrary.split("/");
const splitChunks = splitChunksStr === "1";

webpack(
{
entry: path.resolve(
path.join(compiledDir, path.dirname(libBuildfilePath), entry)
),
output: {
filename: "bundle.js",
path: path.resolve(outputBundleDir),
publicPath: "/",
...(optionalLibrary
? {
library: libraryName,
libraryTarget
}
: {})
},
mode,
target,
module: {
rules: [
{
oneOf: [
{
test: /\.module\.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: true,
camelCase: true
}
},
"postcss-loader"
]
},
{
test: /\.module\.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2,
modules: true,
camelCase: true
}
},
"postcss-loader",
"sass-loader"
]
},
{
test: /\.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1
}
},
"postcss-loader"
]
},
{
test: /\.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2
}
},
"postcss-loader",
"sass-loader"
]
},
{
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
loader: require.resolve("file-loader")
}
]
}
]
},
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node:
target.indexOf("node") === -1
? {
dgram: "empty",
fs: "empty",
net: "empty",
tls: "empty",
child_process: "empty"
}
: {},
resolve: {
modules: [
path.resolve(path.join(installedNpmPackagesDir, "node_modules"))
]
},
resolveLoader: {
modules: [path.resolve(path.join(loadersNpmPackagesDir, "node_modules"))]
},
plugins: [
new HtmlWebpackPlugin({
template: htmlTemplatePath,
inject: true
}),
// Chunk splitting is enabled by default.
...(!splitChunks && [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1
})
])
]
},
(err, stats) => {
// See https://webpack.js.org/api/node/#error-handling.
if (err) {
console.error(err.stack || err);
if (err.details) {
console.error(err.details);
}
process.exit(1);
}
const info = stats.toJson();
if (stats.hasErrors()) {
console.error(info.errors);
process.exit(1);
}
if (stats.hasWarnings()) {
console.warn(info.warnings);
webpack(require(path.resolve(webpackConfigFilePath)), (err, stats) => {
// See https://webpack.js.org/api/node/#error-handling.
if (err) {
console.error(err.stack || err);
if (err.details) {
console.error(err.details);
}
process.exit(1);
}
const info = stats.toJson();
if (stats.hasErrors()) {
console.error(info.errors);
process.exit(1);
}
if (stats.hasWarnings()) {
console.warn(info.warnings);
}
);
});
165 changes: 165 additions & 0 deletions internal/web_bundle/create_webpack_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
const fs = require("fs-extra");
const path = require("path");

const [
nodePath,
scriptPath,
libBuildfilePath,
entry,
htmlTemplatePath,
target,
mode,
optionalLibrary,
splitChunksStr,
loadersNpmPackagesDir,
installedNpmPackagesDir,
sourceDir,
outputBundleDir,
webpackConfigPath
] = process.argv;

const [libraryName, libraryTarget] = optionalLibrary.split("/");
const splitChunks = splitChunksStr === "1";

const config = `const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: path.resolve("${path.join(
sourceDir,
path.dirname(libBuildfilePath),
entry
)}"),
output: {
filename: "bundle.js",
path: path.resolve("${outputBundleDir}"),
publicPath: "/",
${
optionalLibrary
? `library: "${libraryName}",
libraryTarget: "${libraryTarget}",
`
: ""
}
},
mode: "${mode}",
target: "${target}",
module: {
rules: [
{
oneOf: [
{
test: /\\.module\\.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: true,
camelCase: true
}
},
"postcss-loader"
]
},
{
test: /\\.module\\.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2,
modules: true,
camelCase: true
}
},
"postcss-loader",
"sass-loader"
]
},
{
test: /\\.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1
}
},
"postcss-loader"
]
},
{
test: /\\.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2
}
},
"postcss-loader",
"sass-loader"
]
},
{
// Exclude \`js\` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude \`html\` and \`json\` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\\.(js|jsx|mjs)$/, /\\.html$/, /\\.json$/],
use: "file-loader"
}
]
}
]
},
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node:
${JSON.stringify(
target.indexOf("node") === -1
? {
dgram: "empty",
fs: "empty",
net: "empty",
tls: "empty",
child_process: "empty"
}
: {},
null,
2
)},
resolve: {
modules: [
path.resolve("${path.join(installedNpmPackagesDir, "node_modules")}")
]
},
resolveLoader: {
modules: [
path.resolve("${path.join(loadersNpmPackagesDir, "node_modules")}")
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve("${htmlTemplatePath}"),
inject: true
}),
${
// Chunk splitting is enabled by default.
splitChunks
? ""
: `new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1
}),`
}
]
};
`;

fs.writeFileSync(webpackConfigPath, config, "utf8");
Loading

0 comments on commit 201e8e4

Please sign in to comment.