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('/').reduce((foundBabelrc, dir) => {
|
24 | if (foundBabelrc) return foundBabelrc;
|
25 |
|
26 | const indexOf = functionsDir.indexOf(dir);
|
27 | const dirToSearch = functionsDir.substr(0, indexOf);
|
28 |
|
29 | return fs.existsSync(path.join(cwd, dirToSearch, '.babelrc'));
|
30 | }, false)
|
31 | );
|
32 | }
|
33 |
|
34 | function webpackConfig(dir, {userWebpackConfig, useBabelrc} = {}) {
|
35 | var config = conf.load();
|
36 | var envConfig = conf.loadContext(config).environment;
|
37 | var babelOpts = { cacheDirectory: true };
|
38 | if (!haveBabelrc(dir)) {
|
39 | babelOpts.presets = [
|
40 | [require.resolve('@babel/preset-env'), { targets: { node: getBabelTarget(envConfig) } }]
|
41 | ];
|
42 |
|
43 | babelOpts.plugins = [
|
44 | require.resolve('@babel/plugin-proposal-class-properties'),
|
45 | require.resolve('@babel/plugin-transform-object-assign'),
|
46 | require.resolve('@babel/plugin-proposal-object-rest-spread')
|
47 | ];
|
48 | }
|
49 |
|
50 | var functionsDir = config.build.functions || config.build.Functions;
|
51 | var functionsPath = path.join(process.cwd(), functionsDir);
|
52 | var dirPath = path.join(process.cwd(), dir);
|
53 |
|
54 | if (dirPath === functionsPath) {
|
55 | throw new Error(
|
56 | `
|
57 | netlify-lambda Error: Function source folder (specified in netlify-lambda serve/build command) and publish folder (specified in netlify.toml)
|
58 | should be different. They are both set to ${dirPath}.
|
59 |
|
60 | 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".
|
61 | For more info, check https://github.com/netlify/netlify-lambda#usage
|
62 | `
|
63 | );
|
64 | }
|
65 |
|
66 |
|
67 | var defineEnv = {};
|
68 | Object.keys(envConfig).forEach(key => {
|
69 | defineEnv['process.env.' + key] = JSON.stringify(envConfig[key]);
|
70 | });
|
71 |
|
72 |
|
73 | var nodeEnv = process.env.NODE_ENV || 'production'
|
74 |
|
75 |
|
76 | var webpackMode = ['production', 'development'].includes(nodeEnv) ? nodeEnv : 'none'
|
77 |
|
78 | var webpackConfig = {
|
79 | mode: webpackMode,
|
80 | resolve: {
|
81 | extensions: ['.wasm', '.mjs', '.js', '.json', '.ts'],
|
82 | mainFields: ['module', 'main']
|
83 | },
|
84 | module: {
|
85 | rules: [
|
86 | {
|
87 | test: /\.(m?js|ts)?$/,
|
88 | exclude: new RegExp(
|
89 | `(node_modules|bower_components|${testFilePattern})`
|
90 | ),
|
91 | use: {
|
92 | loader: require.resolve('babel-loader'),
|
93 | options: {...babelOpts, babelrc: useBabelrc}
|
94 | }
|
95 | }
|
96 | ]
|
97 | },
|
98 | context: dirPath,
|
99 | entry: {},
|
100 | target: 'node',
|
101 | plugins: [
|
102 | new webpack.IgnorePlugin(/vertx/),
|
103 | new webpack.DefinePlugin(defineEnv)
|
104 | ],
|
105 | output: {
|
106 | path: functionsPath,
|
107 | filename: '[name].js',
|
108 | libraryTarget: 'commonjs'
|
109 | },
|
110 | optimization: {
|
111 | nodeEnv
|
112 | },
|
113 | bail: true,
|
114 | devtool: false
|
115 | };
|
116 | fs.readdirSync(dirPath).forEach(function(file) {
|
117 | if (file.match(/\.(m?js|ts)$/)) {
|
118 | var name = file.replace(/\.(m?js|ts)$/, "");
|
119 | if (!name.match(new RegExp(testFilePattern))) {
|
120 | webpackConfig.entry[name] = "./" + file;
|
121 | }
|
122 | }
|
123 | });
|
124 | if (Object.keys(webpackConfig.entry) < 1) {
|
125 | console.warn(
|
126 | `
|
127 | ---Start netlify-lambda notification---
|
128 | WARNING: No valid single functions files (ending in .mjs, .js or .ts) were found.
|
129 | This could be because you have nested them in a folder.
|
130 | If this is expected (e.g. you have a zipped function built somewhere else), you may ignore this.
|
131 | ---End netlify-lambda notification---
|
132 | `
|
133 | );
|
134 | }
|
135 | if (userWebpackConfig) {
|
136 | var webpackAdditional = require(path.join(process.cwd(), userWebpackConfig));
|
137 |
|
138 | return merge.smart(webpackConfig, webpackAdditional);
|
139 | }
|
140 |
|
141 | return webpackConfig;
|
142 | }
|
143 |
|
144 | exports.run = function(dir, additionalConfig) {
|
145 | return new Promise(function(resolve, reject) {
|
146 | webpack(webpackConfig(dir, additionalConfig), function(err, stats) {
|
147 | if (err) {
|
148 | return reject(err);
|
149 | }
|
150 | resolve(stats);
|
151 | });
|
152 | });
|
153 | };
|
154 |
|
155 | exports.watch = function(dir, additionalConfig, cb) {
|
156 | var compiler = webpack(webpackConfig(dir, additionalConfig));
|
157 | compiler.watch(webpackConfig(dir, additionalConfig), cb);
|
158 | };
|