UNPKG

7.23 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3var fs = require("fs");
4var path = require("path");
5var program = require("commander")
6
7var libdir = path.dirname(process.argv[1]);
8var libmod = libdir + (fs.existsSync(libdir + "/node_modules/webpack") ? "/node_modules" : "/..");
9var command = process.argv[2];
10var context = process.argv[3] && path.resolve(process.argv[3]);
11
12// Print version
13var version = JSON.parse(fs.readFileSync(libdir + "/package.json")).version;
14console.log("Version: react-beaker " + version + "\n");
15program
16 .version(version)
17 .option("-c, --tsconfig [path]", "set tsconfig.json file path")
18 .option("-p, --publicPath [path]", "set publicPath option")
19 .option("-t, --reactToolkit", "build react-toolkit")
20 .option("-h, --hash", "include chunkhash in output filename")
21 .option("-s, --strict", "Set TypeScript strict flag to true")
22 .parse(process.argv);
23
24// Validate arguments
25if (!command || !context || ["watch", "build", "publish"].indexOf(command) < 0) {
26 help();
27 process.exit(1);
28}
29
30// Find all JavaScript entries
31var entry = {};
32var entriesDir = context + "/js/entries/";
33fs.readdirSync(entriesDir).forEach(function(filename) {
34 if (/.*\.sw.$/.test(filename) === false) {
35 entry[filename.replace(/\.[^\.]+$/, "")] = entriesDir + filename;
36 }
37});
38
39// Find all HTML files
40try {
41 var pages = fs.readdirSync(context + "/html").filter(function(filename) {
42 return /.*\.sw.$/.test(filename) === false;
43 });
44} catch (_) {
45 var pages = [];
46}
47
48// Choose options
49var options = {};
50switch (command) {
51 case "watch":
52 options = {
53 "NODE_ENV": '"development"',
54 "filename": "[name].min.js",
55 "minimize": false,
56 "sourceMap": true,
57 };
58 break;
59 case "build":
60 options = {
61 "NODE_ENV": '"production"',
62 "filename": "[name].js",
63 "minimize": false,
64 "sourceMap": false,
65 };
66 break;
67 case "publish":
68 options = {
69 "NODE_ENV": '"production"',
70 "filename": program.hash ? "[name].[chunkhash].min.js" : "[name].min.js",
71 "minimize": true,
72 "sourceMap": false,
73 };
74 break;
75}
76
77// Generate tsconfig.json
78var tsconfig = {
79 compilerOptions: {
80 "jsx": "react",
81 "module": "es2015",
82 "allowSyntheticDefaultImports": true,
83 "moduleResolution": "node",
84 "strict": program.strict,
85 "target": "es5",
86 "lib": ["dom", "es2017"],
87 "experimentalDecorators": true,
88 }
89}
90var tsconfigFile = program.tsconfig && path.resolve(program.tsconfig)
91if (!tsconfig || !fs.existsSync(tsconfigFile)) {
92 fs.writeFileSync(context + "/tsconfig.json", JSON.stringify(tsconfig, null, 2))
93}
94
95var webpack = require(libmod + "/webpack");
96var HtmlWebpackPlugin = require(libmod + "/html-webpack-plugin");
97var autoprefixer = require(libmod + "/autoprefixer");
98var loadersForCSSFile = [
99 {
100 loader: "style-loader"
101 },
102 {
103 loader: "css-loader",
104 options: {
105 minimize: true
106 }
107 },
108 {
109 loader: "postcss-loader",
110 options: {
111 plugins: function() {
112 return [
113 autoprefixer({
114 browsers: ["last 2 versions", "Safari >= 8"]
115 })
116 ];
117 }
118 }
119 }
120]
121
122var compiler = webpack({
123 devtool: options.sourceMap && "inline-source-map",
124 context: context,
125 resolve: {
126 extensions: [".web.js", ".js", ".jsx", ".ts", ".tsx"],
127 alias: {
128 "react/lib": libmod + "/react/lib",
129 }
130 },
131 externals: {
132 "react": "React",
133 "redux": "Redux",
134 "react-dom": "ReactDOM",
135 "react-router": "ReactRouter",
136 "react-addons-css-transition-group": "ReactCSSTransitionGroup",
137 },
138 resolveLoader: {
139 modules: [libmod]
140 },
141 entry: entry,
142 output: {
143 path: context + "/dist",
144 filename: options.filename,
145 publicPath: program.publicPath || ""
146 },
147 module: {
148 rules: [
149 {
150 test: /\.jsx?$/,
151 loader: "babel-loader",
152 exclude: /node_modules/,
153 query: {
154 presets: [
155 libmod + "/babel-preset-react",
156 libmod + "/babel-preset-es2015",
157 ],
158 plugins: [
159 libmod + "/babel-plugin-transform-object-assign",
160 ],
161 },
162 },
163 {
164 test: /\.tsx?$/,
165 loader: "ts-loader",
166 exclude: /node_modules/
167 },
168 {
169 test: /^[^!]+.css$/,
170 use: loadersForCSSFile
171 },
172 {
173 test: /^[^!]+.less$/,
174 use: loadersForCSSFile.concat(
175 {
176 loader: "less-loader"
177 }
178 )
179 },
180 // In Webpack 2, json-loader is no longer needed;
181 /*
182 {
183 test: /\.json$/,
184 loader: "json-loader"
185 }
186 */
187 ],
188 },
189 plugins: pages.map(function(filename) {
190 return new HtmlWebpackPlugin({
191 filename: filename,
192 template: context + "/html/" + filename,
193 });
194 }).concat(options.minimize ? [
195 new webpack.optimize.UglifyJsPlugin({
196 sourceMap: true,
197 compress: {
198 warnings: false
199 }
200 }),
201 new webpack.LoaderOptionsPlugin({
202 minimize: true
203 })
204 ] : []).concat([
205 new webpack.DefinePlugin({
206 "process.env": {
207 NODE_ENV: options.NODE_ENV
208 }
209 })
210 ]),
211 stats: "errors-only",
212});
213
214function buildReactCore() {
215 if (!program.reactToolkit) return
216 webpack({
217 context: libdir,
218 entry: libdir + "/react-toolkit.js",
219 output: {
220 path: context + "/dist",
221 filename: "react-toolkit.min.js",
222 },
223 plugins: [
224 new webpack.optimize.UglifyJsPlugin({
225 minimize: true
226 }),
227 new webpack.DefinePlugin({
228 "process.env": {
229 NODE_ENV: '"production"'
230 }
231 })
232 ]
233 }).run(function() {});
234}
235
236function watch() {
237 buildReactCore();
238 compiler.watch({
239 poll: true
240 }, function(err, stats) {
241 console.log(stats.toString({
242 colors: true
243 }));
244 });
245}
246
247function build() {
248 buildReactCore();
249 compiler.run(function(err, stats) {
250 console.log(stats.toString({
251 colors: true
252 }));
253 if (stats.hasErrors()) process.exit(2);
254 });
255}
256
257function help() {
258 console.error("Usage:");
259 console.error(" react-beaker watch <source dir>");
260 console.error(" react-beaker build <source dir>");
261 console.error(" react-beaker publish <source dir>");
262}
263
264if (command === "watch") watch();
265if (command === "build") build();
266if (command === "publish") build();