UNPKG

4.96 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('/').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
34function 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 // Include environment variables from config if available
67 var defineEnv = {};
68 Object.keys(envConfig).forEach(key => {
69 defineEnv['process.env.' + key] = JSON.stringify(envConfig[key]);
70 });
71
72 // Keep the same NODE_ENV if it was specified
73 var nodeEnv = process.env.NODE_ENV || 'production'
74
75 // Set webpack mode based on the nodeEnv
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
144exports.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
155exports.watch = function(dir, additionalConfig, cb) {
156 var compiler = webpack(webpackConfig(dir, additionalConfig));
157 compiler.watch(webpackConfig(dir, additionalConfig), cb);
158};