1 | var fs = require('fs');
|
2 | var path = require('path');
|
3 | var conf = require('./config');
|
4 | var webpack = require('webpack');
|
5 | var merge = require('webpack-merge');
|
6 |
|
7 | const testFilePattern = '\\.(test|spec)\\.?';
|
8 |
|
9 |
|
10 | function 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 |
|
18 | function 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 |
|
32 | function 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 |
|
69 | var defineEnv = {};
|
70 | Object.keys(envConfig).forEach((key) => {
|
71 | defineEnv['process.env.' + key] = JSON.stringify(envConfig[key]);
|
72 | });
|
73 |
|
74 |
|
75 | var nodeEnv = process.env.NODE_ENV || 'production';
|
76 |
|
77 |
|
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 |
|
154 | exports.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 |
|
169 | exports.watch = function (dir, additionalConfig, cb) {
|
170 | var compiler = webpack(webpackConfig(dir, additionalConfig));
|
171 | compiler.watch(webpackConfig(dir, additionalConfig), cb);
|
172 | };
|