UNPKG

5.34 kBJavaScriptView Raw
1var fs = require('fs');
2var path = require('path');
3var conf = require('./config');
4var webpack = require('webpack');
5var merge = require('webpack-merge');
6
7const testFilePattern = '\\.(test|spec)\\.?';
8
9// custom babel target for each node version
10function getBabelTarget(envConfig) {
11 var key = 'AWS_LAMBDA_JS_RUNTIME';
12 var runtimes = ['nodejs8.15.0', 'nodejs6.10.3'];
13 var current = envConfig[key] || process.env[key] || 'nodejs8.15.0';
14 var unknown = runtimes.indexOf(current) === -1;
15 return unknown ? '8.15.0' : current.replace(/^nodejs/, '');
16}
17
18function haveBabelrc(functionsDir) {
19 const cwd = process.cwd();
20
21 return (
22 fs.existsSync(path.join(cwd, '.babelrc')) ||
23 functionsDir.split('/').some((dir) => {
24 const indexOf = functionsDir.indexOf(dir);
25 const dirToSearch = functionsDir.substr(0, indexOf);
26
27 return fs.existsSync(path.join(cwd, dirToSearch, '.babelrc'));
28 })
29 );
30}
31
32function webpackConfig(dir, { userWebpackConfig, useBabelrc } = {}) {
33 var config = conf.load();
34 var envConfig = conf.loadContext(config).environment;
35 var babelOpts = { cacheDirectory: true };
36 if (!haveBabelrc(dir)) {
37 babelOpts.presets = [
38 [
39 require.resolve('@babel/preset-env'),
40 { targets: { node: getBabelTarget(envConfig) } },
41 ],
42 ];
43
44 babelOpts.plugins = [
45 require.resolve('@babel/plugin-proposal-class-properties'),
46 require.resolve('@babel/plugin-transform-object-assign'),
47 require.resolve('@babel/plugin-proposal-object-rest-spread'),
48 ];
49 }
50
51 var functionsDir = config.build.functions || config.build.Functions;
52 var functionsPath = path.resolve(path.join(process.cwd(), functionsDir));
53 var dirPath = path.resolve(path.join(process.cwd(), dir));
54
55 if (dirPath === functionsPath) {
56 throw new Error(
57 `
58 netlify-lambda Error: Function source folder (specified in netlify-lambda serve/build command) and publish folder (specified in netlify.toml)
59 should be different. They are both set to ${dirPath}.
60
61 This is a common mistake for people switching from Netlify Dev to netlify-lambda. For an easy fix, change your functions key inside netlify.toml to something else, like "functions-build".
62 You will then need to build your functions to that directory before they will work locally and the built functions will also need to be pushed to your repo.
63 For more info, check https://github.com/netlify/netlify-lambda#usage
64 `,
65 );
66 }
67
68 // Include environment variables from config if available
69 var defineEnv = {};
70 Object.keys(envConfig).forEach((key) => {
71 defineEnv['process.env.' + key] = JSON.stringify(envConfig[key]);
72 });
73
74 // Keep the same NODE_ENV if it was specified
75 var nodeEnv = process.env.NODE_ENV || 'production';
76
77 // Set webpack mode based on the nodeEnv
78 var webpackMode = ['production', 'development'].includes(nodeEnv)
79 ? nodeEnv
80 : 'none';
81
82 var webpackConfig = {
83 mode: webpackMode,
84 resolve: {
85 extensions: ['.wasm', '.mjs', '.js', '.json', '.ts'],
86 mainFields: ['module', 'main'],
87 },
88 module: {
89 rules: [
90 {
91 test: /\.(m?js|ts)?$/,
92 exclude: new RegExp(
93 `(node_modules|bower_components|${testFilePattern})`,
94 ),
95 use: {
96 loader: require.resolve('babel-loader'),
97 options: { ...babelOpts, babelrc: useBabelrc },
98 },
99 },
100 ],
101 },
102 context: dirPath,
103 entry: {},
104 target: 'node',
105 plugins: [
106 new webpack.IgnorePlugin(/vertx/),
107 new webpack.DefinePlugin(defineEnv),
108 ],
109 output: {
110 path: functionsPath,
111 filename: '[name].js',
112 libraryTarget: 'commonjs',
113 },
114 optimization: {
115 nodeEnv,
116 },
117 bail: true,
118 devtool: false,
119 stats: {
120 colors: true,
121 },
122 };
123 fs.readdirSync(dirPath).forEach(function (file) {
124 if (file.match(/\.(m?js|ts)$/)) {
125 var name = file.replace(/\.(m?js|ts)$/, '');
126 if (!name.match(new RegExp(testFilePattern))) {
127 webpackConfig.entry[name] = './' + file;
128 }
129 }
130 });
131 if (Object.keys(webpackConfig.entry) < 1) {
132 console.warn(
133 `
134 ---Start netlify-lambda notification---
135 WARNING: No valid single functions files (ending in .mjs, .js or .ts) were found.
136 This could be because you have nested them in a folder.
137 If this is expected (e.g. you have a zipped function built somewhere else), you may ignore this.
138 ---End netlify-lambda notification---
139 `,
140 );
141 }
142 if (userWebpackConfig) {
143 var webpackAdditional = require(path.join(
144 process.cwd(),
145 userWebpackConfig,
146 ));
147
148 return merge.smart(webpackConfig, webpackAdditional);
149 }
150
151 return webpackConfig;
152}
153
154exports.run = function (dir, additionalConfig) {
155 return new Promise(function (resolve, reject) {
156 webpack(webpackConfig(dir, additionalConfig), function (err, stats) {
157 if (err) {
158 return reject(err);
159 }
160 const errors = stats.compilation.errors || [];
161 if (errors.length > 0) {
162 return reject(stats.compilation.errors);
163 }
164 resolve(stats);
165 });
166 });
167};
168
169exports.watch = function (dir, additionalConfig, cb) {
170 var compiler = webpack(webpackConfig(dir, additionalConfig));
171 compiler.watch(webpackConfig(dir, additionalConfig), cb);
172};