-
Notifications
You must be signed in to change notification settings - Fork 7
/
rollup.config.js
180 lines (151 loc) · 4.74 KB
/
rollup.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Find plugins: https://github.com/rollup/awesome
import glob from "glob"
import path from "path"
import { terser } from "rollup-plugin-terser"
import { nodeResolve } from "@rollup/plugin-node-resolve"
import babel from "@rollup/plugin-babel"
import commonjs from "@rollup/plugin-commonjs"
import copy from 'rollup-plugin-copy'
import fs from 'fs';
import replaceHtmlVars from 'rollup-plugin-replace-html-vars';
import livereload from 'rollup-plugin-livereload'
// get build mode
const prodEnv = process.env.BABEL_ENV === "production"
const targetFolder = "public/"
const srcFolder = "src/"
const absolutePath = (dirPath) => path.resolve(__dirname, dirPath)
/**
* This is a simple build pipeline for JavaScript files.
*
* It works by checking for any `.js` files without a leading `_`
* in the name. If so, rollup processes the file using
* the defined babel configuration and spits it out (folder
* paths in tact) in the project's dist folder.
*
* It's intended to be simple and get out of the way as much
* as possible. Unlike other front-end pipelines, this one
* does not associate file names to any particular layout
* or view. Developers have full control over which files
* get loaded by requiring them to add a script tag.
*
* Additionally, the npm scripts are set up to process
* scripts using terser for additional optimization when
* the build is in "production" mode (see `netlify.tml`
* and `package.json`).
*/
const terserPlugin = terser({
output: {
comments: (_, comment) => {
const { value, type } = comment
if (type === "comment2") {
return /@preserve|@license|@cc_on/i.test(value)
}
},
},
})
let workingFolders = [];
/* prepare script import paths */
let scriptFiles = glob.sync(absolutePath("src/!(_)*/!(_)*.js"))
const scriptInputs = scriptFiles.reduce((files, input) => {
const parts = input.split("src/")
const fileKey = parts[parts.length - 1]
return { [fileKey]: absolutePath(input), ...files }
}, {})
const scriptPaths = Object.keys(scriptInputs)
const scriptOutputs = scriptPaths.reduce((files, file) => {
const inputPath = scriptInputs[file]
const parts = inputPath.split("/")
const pathIndex = parts.indexOf("index.js") - 1
const outputPath = parts.slice(pathIndex).join("/")
workingFolders.push(parts[parts.length-2]);
return { [file]: absolutePath(targetFolder + outputPath), ...files }
}, {})
/**
* Do localizations here. Get through every .js file and find i18n occurances, ex.: __()
* extract all texts and save under public/locales/default.json file.
*
* Prepare scripts for localization. Automatically run in production mode only
*/
if(prodEnv){
// set locales folder
if (!fs.existsSync( targetFolder + 'locales/' )){ fs.mkdirSync( targetFolder + 'locales/' ); }
fs.writeFileSync( targetFolder + 'locales/default.json', '{ "language": "default", "texts": {} }', { flag:'w' } ); // set defaults
let scriptFilesAll = glob.sync(absolutePath("src/**/*.js"))
scriptFilesAll.forEach((input) => { i18n(input); });
function i18n(key){ // export i18n
// get current strings
var def = fs.readFileSync( targetFolder + '/locales/default.json', { encoding:'utf8', flag:'r' });
var defJS = JSON.parse(def);
// find strings
if (fs.existsSync( key )){
var temp = fs.readFileSync( key, {encoding:'utf8', flag:'r'});
var regex = [
new RegExp(/__\('(.*?)'/g),
new RegExp(/__\("(.*?)"/g),
new RegExp(/__html\('(.*?)'/g),
new RegExp(/__html\("(.*?)"/g),
new RegExp(/__attr\('(.*?)'/g),
new RegExp(/__attr\("(.*?)"/g),
new RegExp(/__src\('(.*?)'/g),
new RegExp(/__src\("(.*?)"/g)
]
var result; regex.forEach(reg => { while (result = reg.exec(temp)){
defJS['texts'][result[1]] = result[1];
} });
// write default locale
fs.writeFileSync( targetFolder + 'locales/default.json', JSON.stringify(defJS) );
}
}
}
const bundles = scriptPaths.map((key) => {
let sourcemap = true
// plugin list for any build mode
const plugins = [
nodeResolve(),
commonjs(),
babel({
babelHelpers: "bundled",
exclude: "node_modules/**",
comments: false,
}),
copy({
targets: [
{ src: ['public/home/*'], dest: 'public' }
],
// flatten: false
})
]
// plugin list for production mode
if (prodEnv) {
plugins.push(terserPlugin)
plugins.push(
replaceHtmlVars({
files: 'public/*/index.html',
from: /\${timestamp}/g,
to: new Date().getTime(),
})
)
sourcemap = false
// plugin list development mode
}else{
plugins.push(
livereload({
watch: [
path.resolve(__dirname, 'public'),
],
delay: 500,
exts: [ 'html', 'js', 'scss', 'sass', 'css' ]
})
)
}
return {
input: scriptInputs[key],
output: {
file: scriptOutputs[key],
format: "iife",
sourcemap,
},
plugins,
}
})
export default bundles