├── .gitignore
├── README.md
├── build
├── .DS_Store
├── bundle.js
└── index.html
├── client
├── .DS_Store
├── components
│ ├── App.jsx
│ ├── helpers
│ │ ├── Prettify.js
│ │ └── buildConfig.js
│ └── webpackComponents
│ │ ├── DevServer.jsx
│ │ ├── Frontend.jsx
│ │ ├── Image.jsx
│ │ ├── Linting.jsx
│ │ ├── Optimization.jsx
│ │ ├── Plugin.jsx
│ │ ├── Styling.jsx
│ │ ├── Test.jsx
│ │ ├── Transpiler.jsx
│ │ ├── UI.jsx
│ │ └── Utilities.jsx
├── css
│ └── App.css
├── index.html
└── index.js
├── controller
└── data.js
├── filesToServe
└── webpack-config.js
├── models
├── database.js
└── dependencies.js
├── package-lock.json
├── package.json
├── route
├── api.js
└── download.js
├── server
└── server.js
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WebpackConfigAssist
2 |
3 | Please visit our website
4 | ## https://webpack-generator.herokuapp.com/
5 |
6 | **More Features will be updated.**
7 | You can simply click what you want in the file.
8 | You can either download it or copy into your codebase.
9 |
10 | **Author:**
11 | Aryeh Kobrinsky [GitHub](https://github.com/akobrinsky).
12 | Stanley Huang [GitHub](https://github.com/stanpython).
13 | Nick Kruckenberg [GitHub](https://github.com/kruckenberg).
14 | Kadir Gundogdu [GitHub](https://github.com/kadirgund).
15 | Minchan Jun [GitHub](https://github.com/MinchanJun).
16 |
--------------------------------------------------------------------------------
/build/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stanpython/Webpack-Configurator/7aaed0fba9566bf997c24dcab22063edd7584acb/build/.DS_Store
--------------------------------------------------------------------------------
/build/index.html:
--------------------------------------------------------------------------------
1 |
Webpack App
--------------------------------------------------------------------------------
/client/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stanpython/Webpack-Configurator/7aaed0fba9566bf997c24dcab22063edd7584acb/client/.DS_Store
--------------------------------------------------------------------------------
/client/components/App.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import '../css/App.css';
3 | import 'bootstrap/dist/css/bootstrap.min.css';
4 | import Frontend from './webpackComponents/Frontend';
5 | import Test from './webpackComponents/Test';
6 | import UI from './webpackComponents/UI';
7 | import Transpiler from './webpackComponents/Transpiler';
8 | import Styling from './webpackComponents/Styling';
9 | import Image from './webpackComponents/Image';
10 | import Utilities from './webpackComponents/Utilities';
11 | import Linting from './webpackComponents/Linting';
12 | import Optimization from './webpackComponents/Optimization';
13 | import Plugin from './webpackComponents/Plugin';
14 | import 'highlight.js/styles/dracula.css';
15 | import Highlight from 'react-highlight';
16 | import { Prettify } from './helpers/Prettify';
17 | import { fetchedRulesToObjects, merge, buildConfig, buildRequirements, buildList, buildDeps, installScript } from './helpers/buildConfig';
18 | import { CopyToClipboard } from 'react-copy-to-clipboard';
19 | import { Button } from 'react-bootstrap';
20 | // dear iterators, for any questions about the frontend, shoot a slack to Kadir and Burak
21 |
22 | const App = () => {
23 |
24 | const [selected, setSelected] = useState({});
25 | const [store, setStore] = useState('');
26 | const [requirementDisplay, setrequirementDisplay] = useState('');
27 | const [devDisplay, setDevDisplay] = useState('');
28 | const [rules, setRules] = useState({});
29 | const [dependencies, setDependencies] = useState({});
30 | const [devDependencies, setDevDependencies] = useState({});
31 | const [requirements, setRequirements] = useState({});
32 |
33 | let fetched = false;
34 |
35 | const getData = () => {
36 | fetch('/api')
37 | .then(response => response.json())
38 | .then(data => {
39 | const result = fetchedRulesToObjects(data)
40 | setRules(result[0]);
41 | setDependencies(result[1]);
42 | setDevDependencies(result[2]);
43 | setRequirements(result[3]);
44 | })
45 | }
46 |
47 | const getDownload = (requirementDisplay, store) => {
48 | const fileContents = `const path = require('path');\n` + requirementDisplay + `\n\n` + `module.exports = ` + store;
49 |
50 | const postOptions = {
51 | method: 'POST',
52 | headers: { 'Content-Type': 'application/json'},
53 | body: JSON.stringify({ fileContents }),
54 | }
55 |
56 | fetch('/download', postOptions);
57 | }
58 |
59 | useEffect(() => {
60 | if (!fetched) {
61 | getData();
62 | fetched = true;
63 | }
64 |
65 | // Build new config object based on current checkbox selections
66 | let newConfig = buildConfig(selected, rules);
67 | if (newConfig === undefined) { // displays default config object
68 | newConfig = {
69 | entry: './src/index.js',
70 | output: {
71 | path: "path.resolve(__dirname, 'dist')",
72 | filename: 'bundle.js',
73 | },
74 | };
75 | }
76 |
77 | /** Pass newConfig object through Prettify, which returns a string with
78 | * line returns added, quotation marks stripped from regex expressions and
79 | * function invocations. */
80 | let prettified = Prettify(newConfig);
81 | // Update state with prettified string
82 | setStore(prettified);
83 |
84 | // Build new requirements string based on current checkbox selections
85 | let newReqs = buildRequirements(selected, requirements);
86 | // Update state with newly built requirements string
87 | setrequirementDisplay(newReqs);
88 |
89 | // Build script for packages using helper functions
90 | let newDevs = installScript(selected, dependencies, devDependencies);
91 | // Update state with packages as string
92 | setDevDisplay(newDevs);
93 | }, [selected])
94 |
95 |
96 | const handleSelectChange = (name, value) => {
97 | const defaultState = {
98 | nolibrary: false,
99 | react: false,
100 | vue: false,
101 | svelte: false,
102 | }
103 |
104 | if (name === 'nolibrary' || name === 'react' || name === 'vue' || name === 'svelte') {
105 | // console.log('frontend')
106 | setSelected({ ...selected, ...defaultState, [name]: value })
107 | } else {
108 | setSelected({ ...selected, [name]: value })
109 | }
110 | }
111 |
112 | return (
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | {`const path = require('path');\n` + requirementDisplay + `\n\n` + `module.exports = ` + store}
129 |
130 |
131 |
NPM Packages
132 |
133 | {devDisplay}
134 |
135 |
136 |
137 | Copy Script
138 |
139 |
Get Your File
140 |
getDownload(requirementDisplay, store)}>Save Your File
141 |
142 |
143 |
144 |
145 | )
146 |
147 | }
148 |
149 | export default App;
150 |
--------------------------------------------------------------------------------
/client/components/helpers/Prettify.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/prefer-default-export */
2 | const stringifyObject = require('stringify-object');
3 |
4 | export function Prettify(obj) {
5 | return stringifyObject(obj, {
6 | transform: (obj, prop, originalResult) => {
7 | if (prop === 'path' || prop === 'plugins' || prop === 'contentBase' || prop === 'preprocess' || prop === 'exclude') {
8 | return originalResult.replace(/['"]+/g, '').replace(/\\/g, "'");
9 | } if (prop === 'test') {
10 | return originalResult.replace(/['"]+/g, '');
11 | }
12 | return originalResult;
13 | },
14 | indent: ' ',
15 | });
16 | }
17 |
--------------------------------------------------------------------------------
/client/components/helpers/buildConfig.js:
--------------------------------------------------------------------------------
1 | /** fetchedRulesToObjects parses the fetched data into
2 | * three
3 | */
4 | const fetchedRulesToObjects = (rulesArray) => {
5 | const rulesObj = {};
6 | const dependencies = {};
7 | const devDependencies = {};
8 | const requirements = {};
9 |
10 | for (const rule of rulesArray) {
11 |
12 | rulesObj[rule.name] = rule.code || {};
13 | dependencies[rule.name] = rule.dependencies;
14 | devDependencies[rule.name] = rule.devDependencies;
15 | requirements[rule.name] = rule.require;
16 | }
17 |
18 | return [rulesObj, dependencies, devDependencies, requirements];
19 | }
20 |
21 | /** `merge` is a helper function used to merge base config
22 | * object with update objects. `merge` is called from buildConfig
23 | */
24 | const merge = (base, update) => {
25 | /** Helper function used to determine if value is an object */
26 | const isObject = (value) => {
27 | return (
28 | typeof value === 'object' &&
29 | !Array.isArray(value) &&
30 | !(value instanceof RegExp) &&
31 | value !== null
32 | )
33 | };
34 |
35 | /** Loop through keys of update object */
36 | for (const key of Object.keys(update)) {
37 | /** Construct booleans for flow control. Determine if
38 | * both the base and update values at current key are
39 | * arrays or objects.
40 | */
41 | const both = [update[key], base[key]];
42 | const bothArrays = both.every(Array.isArray);
43 | const bothObjects = both.every(isObject);
44 |
45 | /** If both base and update values at current key are arrays,
46 | * concatenate them and store at key on base. If both base
47 | * and update values are objects, make recursive call,
48 | * storing the return at key on base. Otherwise, add or overwrite
49 | * value at key of base with value at key of update.
50 | */
51 | if (bothArrays) {
52 | base[key] = [...base[key], ...update[key]];
53 | if (key === 'extensions') {
54 | base[key] = base[key].filter((val, index, arr) => arr.indexOf(val) === index);
55 | }
56 | } else if (bothObjects) {
57 | base[key] = merge(base[key], update[key]);
58 | } else {
59 | base[key] = update[key];
60 | }
61 | }
62 |
63 | return base;
64 | };
65 |
66 |
67 | /** Helper function that takes in selected state variable (state of checkboxes)
68 | * and returns a filtered array of the names of those boxes that are checked.
69 | */
70 | const buildList = (stateVariables) => {
71 | const toBuild = [];
72 | for (const key in stateVariables) {
73 | if (stateVariables[key]) toBuild.push(key);
74 | }
75 | return toBuild;
76 | }
77 |
78 | /** buildConfig takes selected state variable and update rules,
79 | * uses helper function to convert selected state variable into
80 | * a filtered array, and maps over that array to form an array of
81 | * update objects pulled from update rules. `merge` helper function called
82 | * from within a reducer to combine all update rules in the
83 | * array into a single result object.
84 | */
85 | const buildConfig = (stateVariables, updateObjects) => {
86 | /** Convert stateVariables object into a filtered array.
87 | * Need an array that has the name of all the checkboxes
88 | * that are set to true. The names should match the names
89 | * of the corresponding update in updateObjects.
90 | */
91 | const toBuild = buildList(stateVariables);
92 |
93 | /** Map array of selected boxes to create array of objects to merge */
94 | const buildObjects = toBuild.map((objectName) => updateObjects[objectName]);
95 |
96 | /** Build config object by reducing all update objects to a single object using merge */
97 | return buildObjects.reduce((config, update) => {
98 | return merge(config, update)
99 | }, updateObjects.nolibrary);
100 | };
101 |
102 | /** Returns a string containing requirements matching current checkbox selections. */
103 | const buildRequirements = (stateVariables, requirementsList) => {
104 | // Create an array containing the names of currently checked boxes
105 | const toBuild = buildList(stateVariables);
106 |
107 | // Map over array of checked objects, building an array of matching requirements.
108 | const requirements = toBuild.map((objectName) => requirementsList[objectName]);
109 | // Filter empty strings
110 | const filteredReqs = requirements.filter((item) => item.length > 0);
111 |
112 | // Loop through array of update strings, concatenating them into a single string.
113 | let requirementString = '';
114 | filteredReqs.forEach((el) => requirementString += el + `\n`);
115 |
116 | return requirementString;
117 | }
118 | /** Returns a string containing packages matching current checkbox and radio selections. */
119 | const buildDeps = (stateVariables, depsList) => {
120 | // Create an array containing the names of currently checked boxes and radio buttons
121 | const toBuildReg = buildList(stateVariables);
122 |
123 | // Map over array of checked objects, building an array of matching requirements.
124 | const deps = toBuildReg.map((objectName) => depsList[objectName]);
125 | // Filter empty strings
126 | const filteredDeps = deps.filter((item) => item.length > 0);
127 |
128 | // Loop through array of update strings, concatenating them into a single string.
129 | let depstring = '';
130 | filteredDeps.forEach((el) => {
131 | // Join array as string (remove commas)
132 | if (Array.isArray(el)) {
133 | el = el.join(' ');
134 | }
135 | depstring += el + ` `
136 | });
137 |
138 | return depstring;
139 | }
140 |
141 | //return a string containing dependency state and development dependency state
142 | const installScript = (stateVariables, dep, devDep) => {
143 | //check if the object is empty, return empty string
144 | if (Object.keys(dep).length === 0 && Object.keys(devDep).length === 0) return '';
145 | const reg = buildDeps(stateVariables, dep);
146 | const dev = buildDeps(stateVariables, devDep);
147 |
148 | // npm i reg && npm i -D dev
149 | return `npm i ${reg} && npm i -D ${dev}`
150 | }
151 | export { fetchedRulesToObjects, merge, buildConfig, buildRequirements, buildList, buildDeps, installScript };
--------------------------------------------------------------------------------
/client/components/webpackComponents/DevServer.jsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stanpython/Webpack-Configurator/7aaed0fba9566bf997c24dcab22063edd7584acb/client/components/webpackComponents/DevServer.jsx
--------------------------------------------------------------------------------
/client/components/webpackComponents/Frontend.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import '../../css/App.css';
3 |
4 | const Frontend = (props) => {
5 |
6 | const handleChange = (event) => {
7 |
8 | props.onChange(event.target.value, event.target.checked);
9 | };
10 |
11 | return (
12 |
20 | )
21 | }
22 |
23 | export default Frontend;
--------------------------------------------------------------------------------
/client/components/webpackComponents/Image.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import '../../css/App.css';
3 |
4 | const Image = (props) => {
5 |
6 | const handleChange = (e) => {
7 | props.onChange(e.target.value, e.target.checked);
8 | }
9 |
10 | return (
11 |
17 | )
18 | }
19 |
20 | export default Image;
--------------------------------------------------------------------------------
/client/components/webpackComponents/Linting.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import '../../css/App.css';
3 |
4 | const Linting = (props) => {
5 |
6 | const handleChange = (event) => {
7 | props.onChange(event.target.value, event.target.checked);
8 | };
9 |
10 | return (
11 |
17 | )
18 | }
19 |
20 | export default Linting;
--------------------------------------------------------------------------------
/client/components/webpackComponents/Optimization.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import '../../css/App.css';
3 |
4 | const Optimization = (props) => {
5 |
6 | const handleChange = (e) => {
7 | props.onChange(e.target.value, e.target.checked);
8 | }
9 |
10 | return (
11 |
16 | )
17 | }
18 |
19 | export default Optimization;
--------------------------------------------------------------------------------
/client/components/webpackComponents/Plugin.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import '../../css/App.css';
3 |
4 |
5 | const Plugin = (props) => {
6 |
7 | const handleChange = (e) => {
8 | props.onChange(e.target.value, e.target.checked);
9 | }
10 |
11 | return (
12 |
22 | )
23 | }
24 |
25 | export default Plugin;
--------------------------------------------------------------------------------
/client/components/webpackComponents/Styling.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import '../../css/App.css';
3 |
4 | const Styling = (props) => {
5 |
6 | const handleChange = (e) => {
7 | props.onChange(e.target.value, e.target.checked);
8 | }
9 |
10 | return (
11 |
20 | )
21 | }
22 |
23 | export default Styling;
--------------------------------------------------------------------------------
/client/components/webpackComponents/Test.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import '../../css/App.css';
3 |
4 |
5 | const Test = (props) => {
6 |
7 | const handleChange = (e) => {
8 | props.onChange(e.target.value, e.target.checked);
9 | }
10 |
11 | return (
12 |
23 | )
24 | }
25 |
26 | export default Test;
--------------------------------------------------------------------------------
/client/components/webpackComponents/Transpiler.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import '../../css/App.css';
3 |
4 | const Transpiler = (props) => {
5 |
6 | // here we tie the selections to the state selected, and the logic is so that
7 | // some of the logic is dependent on other radios or checkboxes
8 |
9 | const handleChange = (e) => {
10 | props.onChange(e.target.value, e.target.checked);
11 | }
12 |
13 | return (
14 |
20 | )
21 | }
22 |
23 | export default Transpiler;
--------------------------------------------------------------------------------
/client/components/webpackComponents/UI.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import '../../css/App.css';
3 |
4 | const UI = (props) => {
5 |
6 | const handleChange = (e) => {
7 | props.onChange(e.target.value, e.target.checked);
8 | }
9 |
10 | return (
11 |
17 | )
18 | }
19 |
20 | export default UI;
--------------------------------------------------------------------------------
/client/components/webpackComponents/Utilities.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import '../../css/App.css';
3 |
4 | const Utilities = (props) => {
5 |
6 | const handleChange = (e) => {
7 | props.onChange(e.target.value, e.target.checked);
8 | }
9 |
10 | return (
11 |
17 | )
18 | }
19 |
20 | export default Utilities;
--------------------------------------------------------------------------------
/client/css/App.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: #F5F5F5;
3 | font-family: 'Source Code Pro','Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
4 | font-size: 16px;
5 | color: #282b36;
6 | }
7 | h1 {
8 | text-align: center;
9 | font-family: 'Roboto';
10 | }
11 | header {
12 | margin: 50px 0;
13 | }
14 | .version {
15 | color: #da10e6;
16 | text-shadow: 1px 1px #000000b8, 2px 2px #000000b8, 3px 3px #000000b8;
17 | }
18 | #copy {
19 | margin-top: 30px;
20 | }
21 | #copy .hljs {
22 | padding: 15px;
23 | }
24 | .main-container {
25 | display: flex;
26 | justify-content: center;
27 | width: 1200px;
28 | margin: 0 auto;
29 | padding-bottom: 40px;
30 | }
31 | .component-container {
32 | font-size: 14px;
33 | }
34 | .code-container {
35 | width: 75%;
36 | margin-left: 0;
37 | }
38 | code.javascript.hljs {
39 | min-height: 850px;
40 | border-radius: 8px;
41 | box-shadow: 0 0 8px #00000078;
42 | padding: 25px;
43 | }
44 | strong {
45 | color: #b32e9c;
46 | }
47 | pre {
48 | margin-top: 5px;
49 | }
50 | ul {
51 | margin: 5px 5px 0 0;
52 | padding-left: 0;
53 | }
54 |
55 | li {
56 | list-style: none;
57 | }
58 |
59 | .hljs-attr {
60 | color: #d289cc;
61 | }
62 | .hljs-bullet, .hljs-quote, .hljs-link, .hljs-number, .hljs-regexp, .hljs-literal {
63 | color: #8be9fd !important;
64 | }
65 | .hljs-subst, .hljs-type, .hljs-built_in, .hljs-builtin-name, .hljs-symbol, .hljs-selector-id, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-template-tag, .hljs-template-variable, .hljs-addition {
66 | color: #ffcb06 !important;
67 | }
68 | .btn-outline-dark {
69 | float: right;
70 | }
71 | input[type=checkbox], input[type=radio] {
72 | box-sizing: border-box;
73 | margin-right: 5px;
74 | }
75 | .btn-outline-info {
76 | margin-right: 15px;
77 | float: right;
78 | }
--------------------------------------------------------------------------------
/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 | Webpack Generator 2.0
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/client/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from 'react-dom';
3 | import App from './components/App';
4 |
5 | // should grab the App component and attach to the index.html
6 | render( ,
7 | document.getElementById('root'),
8 | );
--------------------------------------------------------------------------------
/controller/data.js:
--------------------------------------------------------------------------------
1 | const models = require("../models/dependencies");
2 | const dependencies = require("../models/dependencies");
3 | const fs = require('fs');
4 | const path = require('path');
5 | const webpackController = {};
6 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
7 |
8 | // webpackController.add = async (req, res, next) => {
9 | // const arr = [
10 |
11 | // ]
12 | // let request = await models.Library.insertMany(arr);
13 |
14 | // res.locals.added = request;
15 | // next();
16 | // }
17 |
18 | webpackController.getAll = async (req, res, next) => {
19 | const response = await models.Library.find({})
20 | res.locals.data = response;
21 | next();
22 | };
23 |
24 | webpackController.writeFile = async (req, res, next) => {
25 | const textForFile = req.body.fileContents;
26 | fs.writeFileSync(path.resolve(__dirname, '../filesToServe/webpack-config.js'), textForFile);
27 | next();
28 | }
29 |
30 |
31 |
32 | module.exports = webpackController;
33 |
34 | // {
35 | // name: "tailwindcss",
36 | // code: {
37 | // module: {
38 | // rules: [
39 | // {
40 | // test: "/\.css$/",
41 | // use: [
42 | // 'style-loader',
43 | // {
44 | // loader: 'css-loader',
45 | // options: {
46 | // importLoaders: 1
47 | // }
48 | // },
49 | // 'postcss-loader'
50 | // ]
51 | // }
52 | // ]
53 | // }
54 | // },
55 | // require: "",
56 | // dependencies: ["tailwindcss"],
57 | // devDependencies: []
58 | // },
59 | // {
60 | // name: "cssmodules",
61 | // code: {
62 | // module: {
63 | // rules: [
64 | // {
65 | // test: "/\.css$/",
66 | // use: [
67 | // "style-loader",
68 | // {
69 | // loader: "css-loader",
70 | // options: {
71 | // importLoaders: 1,
72 | // modules: true,
73 | // },
74 | // },
75 | // ],
76 | // },
77 | // ],
78 | // },
79 | // },
80 | // require: "",
81 | // dependencies: [],
82 | // devDependencies: ["css-loader", "style-loader"]
83 | // }
84 |
85 | // {
86 | // name: "webpackbundleanalyzer",
87 | // code: {
88 | // plugins: [
89 | // new BundleAnalyzerPlugin({
90 | // analyzerMode: "static",
91 | // openAnalyzer: false,
92 | // })
93 | // ]
94 | // },
95 | // require: "const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;",
96 | // dependencies: [],
97 | // devDependencies: ["webpack-bundle-analyzer"]
98 | // }
99 |
100 | // {
101 | // name: "prettier",
102 | // code: {},
103 | // require: "",
104 | // dependencies: [],
105 | // devDependencies: ["prettier", "eslint-config-prettier", "eslint-plugin-prettier"]
106 | // }
107 |
108 | // {
109 | // name: "eslint",
110 | // code: {},
111 | // require: "",
112 | // dependencies: [],
113 | // devDependencies: ["eslint"]
114 | // }
115 |
116 | // {
117 | // name: "testcafe",
118 | // code: {},
119 | // require: "",
120 | // dependencies: [],
121 | // devDependencies: ["testcafe"]
122 | // }
123 |
124 | // {
125 | // name: "cypress",
126 | // code: {},
127 | // require: "",
128 | // dependencies: [],
129 | // devDependencies: ["cypress"]
130 | // }
131 |
132 | // {
133 | // name: "ava",
134 | // code: {},
135 | // require: "",
136 | // dependencies: [],
137 | // devDependencies: ["ava"]
138 | // }
139 |
140 | // {
141 | // name: "jasmine",
142 | // code: {},
143 | // require: "",
144 | // dependencies: [],
145 | // devDependencies: ["jasmine"]
146 | // }
147 |
148 | // {
149 | // name: "chai",
150 | // code: {},
151 | // require: "",
152 | // dependencies: [],
153 | // devDependencies: ["chai"]
154 | // }
155 |
156 | // {
157 | // name: "mocha",
158 | // code: {},
159 | // require: "",
160 | // dependencies: [],
161 | // devDependencies: ["mocha"]
162 | // }
163 |
164 | // {
165 | // name: "jest",
166 | // code: {},
167 | // require: "",
168 | // dependencies: [],
169 | // devDependencies: ["jest"]
170 | // }
171 |
172 | // {
173 | // name: "bootstrap",
174 | // code: {},
175 | // require: "",
176 | // dependencies: ["bootstrap", "jquery", "popper.js"],
177 | // devDependencies: ["css-loader", "style-loader"]
178 | // }
179 |
180 | // {
181 | // name: "cleanwebpackplugin",
182 | // code: {
183 | // plugins: [
184 | // "new CleanWebpackPlugin()"
185 | // ]
186 | // },
187 | // require: "const { CleanWebpackPlugin } = require('clean-webpack-plugin');",
188 | // dependencies: [],
189 | // devDependencies: ["clean-webpack-plugin"]
190 | // }
191 |
192 | // {
193 | // name: "copywebpackplugin",
194 | // code: {
195 | // plugins: [
196 | // "new CopyPlugin({ patterns: [{ from: 'src/index.html' }], })"
197 | // ],
198 | // },
199 | // require: "const CopyPlugin = require('copy-webpack-plugin');",
200 | // dependencies: [],
201 | // devDependencies: ["copy-webpack-plugin"]
202 | // }
203 |
204 | // {
205 | // name: "minicssextractplugin",
206 | // code: {
207 | // plugins: [
208 | // "new BundleAnalyzerPlugin({ analyzerMode: 'static', openAnalyzer: false, })"
209 | // ],
210 | // },
211 | // require: "const MiniCssExtractPlugin = require('mini-css-extract-plugin');",
212 | // dependencies: [],
213 | // devDependencies: ["mini-css-extract-plugin"]
214 | // }
215 |
216 | // {
217 | // name: "htmlwebpackplugin",
218 | // code: {
219 | // plugins: [
220 | // "new HtmlWebpackPlugin({ appMountId: 'app', filename: 'index.html'})"
221 | // ],
222 | // },
223 | // require: "const HtmlWebpackPlugin = require('html-webpack-plugin');",
224 | // dependencies: [],
225 | // devDependencies: ["html-webpack-plugin"]
226 | // }
227 |
228 | // {
229 | // name: "codesplitvendor",
230 | // code: {
231 | // output: {
232 | // filename: "[name].[contenthash].js"
233 | // },
234 | // module: {
235 | // rules: [
236 | // {
237 | // test: "/\.js$/",
238 | // use: "babel-loader",
239 | // exclude: "/node_modules/"
240 | // },
241 | // ],
242 | // },
243 | // optimization: {
244 | // runtimeChunk: "single",
245 | // splitChunks: {
246 | // cacheGroups: {
247 | // vendor: {
248 | // test: "/[\\/]node_modules[\\/]/",
249 | // name: "vendors",
250 | // chunks: "all",
251 | // },
252 | // },
253 | // },
254 | // },
255 | // devServer: {
256 | // contentBase: './dist',
257 | // },
258 | // },
259 | // require: "",
260 | // dependencies: [],
261 | // devDependencies: ["html-webpack-plugin"]
262 | // }
263 |
264 | // {
265 | // name: "lodash",
266 | // code: {
267 | // plugins: [
268 | // "new LodashModuleReplacementPlugin"
269 | // ],
270 | // },
271 | // require: "const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');",
272 | // dependencies: ["lodash"],
273 | // devDependencies: ["lodash-webpack-plugin"]
274 | // }
275 |
276 | // {
277 | // name: "moment",
278 | // code: {
279 | // plugins: [
280 | // "new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en/)"
281 | // ]
282 | // },
283 | // require: "",
284 | // dependencies: [
285 | // "moment"
286 | // ],
287 | // devDependencies: []
288 | // }
289 |
290 | // {
291 | // name: "typescript",
292 | // code: {
293 | // entry: "./src/index.ts",
294 | // module: {
295 | // rules: [
296 | // {
297 | // test: "/\.ts(x)?$/",
298 | // loader: "ts-loader",
299 | // exclude: "/node_modules/",
300 | // },
301 | // ],
302 | // },
303 | // resolve: {
304 | // extensions: [
305 | // ".tsx",
306 | // ".ts",
307 | // ".js",
308 | // ],
309 | // },
310 | // },
311 | // require: "",
312 | // dependencies: [],
313 | // devDependencies: ["typescript", "ts-loader", "@types/react", "types/react-dom"]
314 | // }
315 |
316 | // {
317 | // name: "less",
318 | // code: {
319 | // module: {
320 | // rules: [
321 | // {
322 | // test: "/\.less$/",
323 | // use: [
324 | // "style-loader",
325 | // "css-loader",
326 | // "less-loader",
327 | // ],
328 | // },
329 | // ],
330 | // },
331 | // },
332 | // require: "",
333 | // dependencies: [],
334 | // devDependencies: ["css-loader", "less-loader", "less", "style-loader"]
335 | // }
336 |
337 | // {
338 | // name: "stylus",
339 | // code: {
340 | // module: {
341 | // rules: [
342 | // {
343 | // test: "/\.styl$/",
344 | // use: [
345 | // "style-loader",
346 | // "css-loader",
347 | // "stylus-loader",
348 | // ],
349 | // },
350 | // ],
351 | // },
352 | // },
353 | // require: "",
354 | // dependencies: [],
355 | // devDependencies: ["css-loader", "stylus-loader", "stylus", "style-loader"]
356 | // }
357 |
358 | // {
359 | // name: "svg",
360 | // code: {
361 | // module: {
362 | // rules: [
363 | // {
364 | // test: "/\.svg$/",
365 | // use: "file-loader",
366 | // },
367 | // ],
368 | // },
369 | // },
370 | // require: "",
371 | // dependencies: [],
372 | // devDependencies: ["file-loader"]
373 | // }
374 |
375 | // {
376 | // name: "png",
377 | // code: {
378 | // module: {
379 | // rules: [
380 | // {
381 | // test: '/\.png$/',
382 | // use: [
383 | // {
384 | // loader: 'url-loader',
385 | // options: {
386 | // mimetype: 'image/png',
387 | // },
388 | // },
389 | // ],
390 | // },
391 | // ],
392 | // },
393 | // },
394 | // require: "",
395 | // dependencies: [],
396 | // devDependencies: ["url-loader"]
397 | // }
398 |
399 | // {
400 | // name: "nolibrary",
401 | // code: {
402 | // entry: './src/index.js',
403 | // output: {
404 | // path: "path.resolve(__dirname, 'dist')",
405 | // filename: 'bundle.js',
406 | // },
407 | // },
408 | // require: "",
409 | // dependencies: [],
410 | // devDependencies: []
411 | // }
412 |
413 | // {
414 | // name: "svelte",
415 | // code: {
416 | // module: {
417 | // rules: [
418 | // {
419 | // test: "/\.svelte$/",
420 | // loader: 'svelte-loader',
421 | // options: {
422 | // preprocess: "require('svelte-preprocess')({})",
423 | // },
424 | // },
425 | // ],
426 | // },
427 | // resolve: {
428 | // extensions: [
429 | // '.mjs',
430 | // '.js',
431 | // '.svelte',
432 | // ],
433 | // },
434 | // },
435 | // require: "",
436 | // dependencies: [],
437 | // devDependencies: ["svelte", "svelte-loader", "svelte-preprocess"]
438 | // }
439 |
440 | // {
441 | // name: "vue",
442 | // code: {
443 | // module: {
444 | // rules: [
445 | // {
446 | // test: "/\.vue$/",
447 | // loader: 'vue-loader',
448 | // },
449 | // ],
450 | // },
451 | // resolve: {
452 | // extensions: [
453 | // '.js',
454 | // '.vue',
455 | // ],
456 | // },
457 | // plugins: [
458 | // "new VueLoaderPlugin()"
459 | // ],
460 | // },
461 | // require: "const VueLoaderPlugin = require('vue-loader/lib/plugin');",
462 | // dependencies: ["vue"],
463 | // devDependencies: ["vue-loader", "vue-template-compiler", "babel-loader", "@babel-core", "@babel/preset-env"]
464 | // }
465 |
466 | // {
467 | // name: "babel",
468 | // code: {
469 | // module: {
470 | // rules: [
471 | // {
472 | // test: "/\.(js|jsx)$/",
473 | // use: {
474 | // loader: 'babel-loader',
475 | // options: {
476 | // presets: ['@babel/preset-env', '@babel/preset-react'],
477 | // },
478 | // },
479 | // },
480 | // ],
481 | // },
482 | // resolve: {
483 | // extensions: [
484 | // '.js',
485 | // '.jsx',
486 | // ],
487 | // },
488 | // },
489 | // require: "",
490 | // dependencies: [],
491 | // devDependencies: ["babel-loader", "@babel-core", "@babel/preset-env"]
492 | // }
493 |
494 | // {
495 | // name: "css",
496 | // code: {
497 | // modules: {
498 | // rules: [
499 | // {
500 | // test: /\.css$/,
501 | // use: [
502 | // 'style-loader',
503 | // 'css-loader',
504 | // ],
505 | // },
506 | // ],
507 | // },
508 | // },
509 | // require: "",
510 | // dependencies: [],
511 | // devDependencies: ["css-loader", "style-loader"]
512 | // }
513 |
514 | // {
515 | // name: "react",
516 | // code: {
517 | // modules: {
518 | // rules: [
519 | // {
520 | // test: "/\.(js|jsx)$/",
521 | // use: "babel-loader",
522 | // exclude: "/node_modules/"
523 | // },
524 | // ],
525 | // },
526 | // resolve: {
527 | // extensions: [
528 | // '.js',
529 | // '.jsx',
530 | // ],
531 | // }
532 | // },
533 | // require: "",
534 | // dependencies: ["react", "react-dom", "react-hot-loader"],
535 | // devDependencies: ["webpack", "webpack-cli", "babel-loader", "@babel/core", "@babel/preset-env", "@hot-loader/react-dom", "@babel/preset-react", "webpack-dev-server"]
536 | // }
537 |
538 |
539 | // {
540 | // name: "sass",
541 | // code: {
542 | // modules: {
543 | // rules: [
544 | // {
545 | // test: "/\.scss$/",
546 | // use: [
547 | // 'style-loader',
548 | // 'css-loader',
549 | // 'sass-loader',
550 | // ],
551 | // },
552 | // ],
553 | // },
554 | // },
555 | // require: "",
556 | // dependencies: [],
557 | // devDependencies: ["css-loader", "style-loader", "sass-loader", "node-sass"]
558 | // }
559 |
560 |
561 |
562 | // =========================================== ===============================================
563 |
564 |
565 | // const db = require('../models/database');
566 | // // const { query } = require('express');
567 | // const dataObj = {};
568 |
569 | // // Query database to receive all entries. Then organize entries and store each 'name' as a key on object with the properties of
570 | // // 'name' being the other columns. Send organized data to the frontend.
571 | // dataObj.getAll = (req, res, next) => {
572 | // const queryTest = 'SELECT * FROM "public"."webpack" LIMIT 100';
573 | // db.query(queryTest).then((data) => {
574 | // const obj = {};
575 | // data.rows.forEach((el) => {
576 | // obj[el.name] = {
577 | // npm: el.npm,
578 | // code: el.code,
579 | // description: el.description,
580 | // require: el.require,
581 | // };
582 | // });
583 |
584 | // res.locals.data = obj;
585 |
586 | // next();
587 | // });
588 | // };
589 |
590 | // module.exports = dataObj;
591 |
--------------------------------------------------------------------------------
/filesToServe/webpack-config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 |
4 | module.exports = {
5 | entry: './src/index.js',
6 | output: {
7 | path: path.resolve(__dirname, 'dist'),
8 | filename: 'bundle.js'
9 | },
10 | module: {
11 | rules: [
12 | {
13 | test: /.(js|jsx)$/,
14 | use: 'babel-loader',
15 | exclude: /node_modules/
16 | },
17 | {
18 | test: /.(js|jsx)$/,
19 | use: {
20 | loader: 'babel-loader',
21 | options: {
22 | presets: [
23 | '@babel/preset-env',
24 | '@babel/preset-react'
25 | ]
26 | }
27 | }
28 | },
29 | {
30 | test: /\.css$/,
31 | use: [
32 | 'style-loader',
33 | 'css-loader'
34 | ]
35 | }
36 | ]
37 | },
38 | resolve: {
39 | extensions: [
40 | '.js',
41 | '.jsx'
42 | ]
43 | }
44 | }
--------------------------------------------------------------------------------
/models/database.js:
--------------------------------------------------------------------------------
1 | const { Pool } = require('pg');
2 |
3 | // ElephantSQL URI - Send Taylor or Patrick a Slack for access to database
4 | const PG_URI =
5 | 'postgres://qquarylc:9f-WympV5l824vTHMGwyNrlOfAM572tk@raja.db.elephantsql.com:5432/qquarylc';
6 |
7 | // Pool creates an open connection to database
8 | // https://node-postgres.com/features/pooling
9 | const pool = new Pool({
10 | connectionString: PG_URI,
11 | });
12 |
13 | module.exports = {
14 | query: (text, params, callback) => {
15 | console.log('executed query', text);
16 | return pool.query(text, params, callback);
17 | },
18 | };
19 |
--------------------------------------------------------------------------------
/models/dependencies.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | const MONGO_URI = 'mongodb+srv://webpackconfigassist:Codesmith55463@cluster0.n48qo.mongodb.net/webpackconfig?retryWrites=true&w=majority';
4 | // const string = 'mongorestore --uri="mongodb+srv://webpackconfigassist:Codesmith55463@cluster0.n48qo.mongodb.net/?retryWrites=true&w=majority"'
5 |
6 | mongoose.connect(MONGO_URI, {
7 | // options for the connect method to parse the URI
8 | useNewUrlParser: true,
9 | useUnifiedTopology: true,
10 | // sets the name of the DB that our collections are part of
11 | dbName: 'webpackconfig'
12 | })
13 | .then(() => console.log('Connected to Mongo DB.'))
14 | .catch(err => console.log(err));
15 |
16 | const Schema = mongoose.Schema;
17 |
18 | // sets a schema for the 'dependencies' collection
19 | const dependenciesSchema = new Schema({
20 | name: { type: String, unique: true },
21 | code: { type: Object, required: true, },
22 | require: String,
23 | dependencies: Array,
24 | devDependencies: Array
25 | });
26 |
27 | // creats a model for the 'dependencies' collection that will be part of the export
28 | const Dependencies = mongoose.model('dependencies', dependenciesSchema);
29 |
30 | const librarySchema = new Schema({
31 | name: { type: String, unique: true },
32 | code: { type: Object, required: true, },
33 | require: String,
34 | dependencies: Array,
35 | devDependencies: Array
36 | });
37 |
38 | const Library = mongoose.model('library', librarySchema);
39 |
40 | // exports the model in an object to be used in the controller
41 | module.exports = { Dependencies, Library };
42 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "WebpackConfigAssist",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "dev": "concurrently \"cross-env NODE_ENV=development webpack-dev-server --open --hot \" \"nodemon server/server.js\"",
9 | "start": "NODE_ENV=production nodemon server/server.js",
10 | "build": "NODE_ENV=production webpack"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/patrick934/WebpackConfigAssist.git"
15 | },
16 | "keywords": [],
17 | "author": "",
18 | "license": "ISC",
19 | "bugs": {
20 | "url": "https://github.com/patrick934/WebpackConfigAssist/issues"
21 | },
22 | "homepage": "https://github.com/patrick934/WebpackConfigAssist#readme",
23 | "dependencies": {
24 | "@babel/plugin-transform-runtime": "^7.11.0",
25 | "@reduxjs/toolkit": "^1.4.0",
26 | "bootstrap": "^4.5.2",
27 | "concurrently": "^5.3.0",
28 | "cors": "^2.8.5",
29 | "express": "^4.17.1",
30 | "highlight.js": "^10.1.2",
31 | "hot-module-replacement": "^3.0.4",
32 | "mini-css-extract-plugin": "^0.10.0",
33 | "mongoose": "^5.10.0",
34 | "node-fetch": "^2.6.0",
35 | "nodemon": "^2.0.4",
36 | "pg": "^8.3.0",
37 | "react": "^16.13.1",
38 | "react-bootstrap": "^1.3.0",
39 | "react-copy-to-clipboard": "^5.0.2",
40 | "react-dom": "^16.13.1",
41 | "react-highlight": "^0.12.0",
42 | "react-router": "^5.2.0",
43 | "react-router-dom": "^5.2.0",
44 | "redux": "^4.0.5",
45 | "stringify-object": "^3.3.0",
46 | "webpack-bundle-analyzer": "^3.8.0",
47 | "webpack-dev-server": "^3.11.0",
48 | "webpack-node-externals": "^2.5.1"
49 | },
50 | "devDependencies": {
51 | "@babel/core": "^7.11.1",
52 | "@babel/preset-env": "^7.11.0",
53 | "@babel/preset-react": "^7.10.4",
54 | "babel-loader": "^8.1.0",
55 | "cross-env": "^7.0.2",
56 | "css-loader": "^4.2.1",
57 | "html-webpack-plugin": "^4.3.0",
58 | "sass-loader": "^9.0.3",
59 | "style-loader": "^1.2.1",
60 | "webpack": "^4.44.1",
61 | "webpack-cli": "^3.3.12"
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/route/api.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | // const dataController = require('../controller/data');
3 | const router = express.Router();
4 | const webpackController = require('../controller/data');
5 |
6 | // router.use('/add', webpackController.add, (req, res) => {
7 | // res.status(202).json(res.locals.added);
8 | // });
9 |
10 | router.use('/', webpackController.getAll, (req, res) => {
11 | res.status(202).json(res.locals.data);
12 | });
13 |
14 | module.exports = router;
15 |
--------------------------------------------------------------------------------
/route/download.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const webpackController = require('../controller/data');
4 | const path = require('path');
5 | const { config } = require('process');
6 |
7 | router.post('/', webpackController.writeFile, (req, res) => {
8 | res.download(path.resolve(__dirname, '../filesToServe', 'webpack-config.js'));
9 | });
10 |
11 | router.get('/', (req, res) => {
12 | res.download(path.resolve(__dirname, '../filesToServe', 'webpack-config.js'));
13 | });
14 |
15 | module.exports = router;
--------------------------------------------------------------------------------
/server/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const app = express();
3 | const path = require('path');
4 | const cors = require('cors');
5 |
6 | // Require cors to prevent error
7 | // The error is most likely related to HTTP headers
8 | // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
9 |
10 | app.use(cors())
11 | app.use(express.json());
12 | app.use(express.urlencoded());
13 |
14 | const apiRoute = require('../route/api');
15 | const downloadRoute = require('../route/download');
16 | app.use('/api', apiRoute);
17 | app.use('/download', downloadRoute);
18 |
19 | if (process.env.NODE_ENV === 'production') {
20 | app.use('/build', express.static(path.join(__dirname, '../build')));
21 |
22 | app.get('/', (req, res) => {
23 | res.sendFile(path.resolve(__dirname, '../client/index.html'));
24 | });
25 | }
26 |
27 | app.listen(process.env.PORT || 3000, () => console.log('Listening on port 3000...'));
28 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const path = require('path');
3 | const HtmlWebpackPlugin = require('html-webpack-plugin');
4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
5 |
6 | module.exports = {
7 | entry: path.resolve(__dirname, './client/index.js'),
8 | output: {
9 | path: path.resolve(__dirname, 'build'),
10 | filename: 'bundle.js',
11 | },
12 | module: {
13 | rules: [
14 | {
15 | test: /\.jsx?/,
16 | exclude: /node_modules/,
17 | use: {
18 | loader: 'babel-loader',
19 | options: {
20 | presets: ['@babel/preset-env', '@babel/preset-react'],
21 | plugins: ['@babel/plugin-transform-runtime'],
22 | },
23 | },
24 | },
25 | {
26 | test: /\.css$/i,
27 | use: ['style-loader', 'css-loader'],
28 | },
29 | ],
30 | },
31 | plugins: [new HtmlWebpackPlugin(), new MiniCssExtractPlugin()],
32 | mode: process.env.NODE_ENV,
33 | resolve: {
34 | extensions: ['.js', '.jsx'],
35 | },
36 | devServer: {
37 | // host: 'localhost',
38 | // port: 8080,
39 | contentBase: path.join(__dirname, './client'),
40 | publicPath: '/build/',
41 | historyApiFallback: true,
42 | hot: true,
43 | proxy: {
44 | '/api': 'http://localhost:3000',
45 | '/download': 'http://localhost:3000',
46 | },
47 | },
48 | };
49 |
--------------------------------------------------------------------------------