Skip to content

Commit f578cab

Browse files
committed
initial commit
0 parents  commit f578cab

File tree

5 files changed

+267
-0
lines changed

5 files changed

+267
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

bs-config.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"port": 3000,
3+
"files": ["./dist/**/*.{html,css,js}"],
4+
"server": { "baseDir": "./dist" },
5+
"injectChanges": true,
6+
"notify": false,
7+
"ghostMode": false,
8+
"logLevel": "silent",
9+
"proxy": null
10+
}

package.json

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "theme-mix",
3+
"version": "0.1.0",
4+
"author": "FrontendMatter <contact@frontendmatter.com> (http://themeforest.net/user/frontendmatter/portfolio)",
5+
"dependencies": {
6+
"del": "^2.2.2",
7+
"front-matter-loader": "^0.1.2",
8+
"fs-simple-cache": "^1.0.0",
9+
"jsbeautify-loader": "^0.3.0",
10+
"laravel-mix": "^0.10.0",
11+
"lodash.merge": "^4.6.0",
12+
"nunjucks-html-loader": "github:lazabogdan/nunjucks-html-loader#front-matter",
13+
"sass-importer-npm": "^1.0.2",
14+
"webpack-rtl-plugin": "^1.6.0",
15+
"webpack-rtl-wrap-plugin": "^1.2.0",
16+
"webpack-sources": "^0.2.3",
17+
"yargs": "^7.0.2"
18+
},
19+
"description": "Webpack config for FrontendMatter HTML Themes",
20+
"main": "webpack.mix.js",
21+
"scripts": {
22+
"test": "echo \"Error: no test specified\" && exit 1"
23+
},
24+
"license": "ISC"
25+
}

webpack-wrap-theme-plugin.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const async = require('async')
2+
const RawSource = require('webpack-sources').RawSource
3+
const merge = require('lodash.merge')
4+
const Cache = require('fs-simple-cache')
5+
6+
class WebpackWrapThemePlugin {
7+
constructor (options = {}) {
8+
this.options = merge({
9+
test: /\.css?$/,
10+
themeClass: '.theme-default',
11+
}, options)
12+
}
13+
14+
apply (compiler) {
15+
const cache = new Cache(this.options)
16+
compiler.plugin('emit', (compilation, callback) => {
17+
async.eachOfLimit(compilation.chunks, 5, (chunk, key, cb) => {
18+
let promise = Promise.resolve()
19+
20+
chunk.files.forEach((file) => {
21+
const asset = compilation.assets[file]
22+
23+
if (this.options.test.test(file)) {
24+
const source = asset.source()
25+
let content
26+
if (content = cache.get(source).content) {
27+
promise = promise.then(() => content)
28+
}
29+
else {
30+
promise = promise.then(() => {
31+
const result = source.replace(/\[dir=/g, this.options.themeClass + '[dir=')
32+
cache.put(source, { content: result })
33+
return result
34+
})
35+
}
36+
promise = promise.then(result => {
37+
compilation.assets[file] = new RawSource(result)
38+
})
39+
}
40+
})
41+
42+
promise.then(() => cb())
43+
}, callback)
44+
})
45+
}
46+
}
47+
48+
module.exports = WebpackWrapThemePlugin

webpack.mix.js

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
const { mix } = require('laravel-mix')
2+
const Mix = mix.config
3+
const glob = require('glob')
4+
const argv = require('yargs').argv
5+
const del = require('del')
6+
const merge = require('webpack-merge').smart
7+
let webpackConfig = {}
8+
9+
///////////////////////////////////////////
10+
// RUN SPECIFIC TASKS //
11+
// npm run development -- --env.run html //
12+
// npm run development -- --env.run js //
13+
// npm run development -- --env.run sass //
14+
// npm run development -- --env.run copy //
15+
///////////////////////////////////////////
16+
17+
const __RUN = argv.env ? argv.env.run : undefined
18+
19+
/////////////
20+
// CLEANUP //
21+
/////////////
22+
23+
if (__RUN === 'clean' || !__RUN) {
24+
del.sync([
25+
'dist/**/*.html',
26+
'dist/assets/{css,fonts,js,vendor}'
27+
])
28+
}
29+
30+
////////
31+
// JS //
32+
////////
33+
34+
// npm run development -- --env.run js
35+
if (__RUN === 'js' || !__RUN) {
36+
for (let file of glob.sync('./src/js/**/**.{js,vue}', { ignore: '**/_*' })) {
37+
mix.js(file, './dist/assets/js')
38+
}
39+
}
40+
41+
////////////////////////
42+
// COPY VENDOR ASSETS //
43+
// from node_modules //
44+
////////////////////////
45+
46+
// npm run development -- --env.run copy
47+
if (__RUN === 'copy' || !__RUN) {
48+
try {
49+
require(path.join(process.cwd(), 'copy-vendor-assets.json')).forEach(function(asset) {
50+
var dest = path.join(process.cwd(), 'dist/assets/vendor')
51+
var src = asset
52+
if (asset instanceof Object) {
53+
src = Object.keys(asset).pop()
54+
dest = Object.values(asset).pop()
55+
}
56+
for (let file of glob.sync(src, { cwd: path.join(process.cwd(), 'node_modules/') })) {
57+
mix.copy(path.join(process.cwd(), 'node_modules', file), dest)
58+
}
59+
})
60+
}
61+
catch (e) {}
62+
}
63+
64+
//////////
65+
// SASS //
66+
//////////
67+
68+
// npm run development -- --env.theme dark
69+
const __THEME = argv.env ? argv.env.theme || 'default' : 'default'
70+
71+
// npm run development -- --env.run sass
72+
if (__RUN === 'sass' || !__RUN) {
73+
74+
let sassOptions = {
75+
importer: require('sass-importer-npm'),
76+
// inject $theme variable
77+
data: '$theme: ' + __THEME + ';'
78+
}
79+
80+
mix.options({
81+
// ignore fonts
82+
processCssUrls: false
83+
})
84+
85+
for (let file of glob.sync('src/sass/*.scss', { ignore: '**/_*' })) {
86+
mix.sass(file, './dist/assets/css/themes/' + __THEME, sassOptions)
87+
}
88+
}
89+
90+
/////////
91+
// RTL //
92+
/////////
93+
94+
// npm run development -- --env.run sass
95+
if (__RUN === 'sass' || !__RUN) {
96+
const WebpackRTLPlugin = require('webpack-rtl-plugin')
97+
const WebpackRTLWrapPlugin = require('webpack-rtl-wrap-plugin')
98+
const cacheDirectory = path.resolve(path.join('temp', 'rtl', __THEME))
99+
100+
del.sync(cacheDirectory)
101+
102+
webpackConfig = merge(webpackConfig, {
103+
plugins: [
104+
// Creates .rtl.css
105+
new WebpackRTLPlugin({
106+
minify: false
107+
}),
108+
// wraps CSS into [dir=ltr|rtl]
109+
new WebpackRTLWrapPlugin({
110+
cacheDirectory
111+
})
112+
]
113+
})
114+
}
115+
116+
///////////////////////////////////
117+
// WRAP CSS with .theme-$__THEME //
118+
///////////////////////////////////
119+
120+
// npm run development -- --env.run sass
121+
if (__RUN === 'sass' || !__RUN) {
122+
const WebpackWrapThemePlugin = require('./webpack-wrap-theme-plugin')
123+
const cacheDirectory = path.resolve(path.join('temp', 'themeClass', __THEME))
124+
125+
del.sync(cacheDirectory)
126+
127+
webpackConfig = merge(webpackConfig, {
128+
plugins: [
129+
new WebpackWrapThemePlugin({
130+
themeClass: '.theme-' + __THEME,
131+
cacheDirectory
132+
})
133+
]
134+
})
135+
}
136+
137+
//////////////
138+
// NUNJUCKS //
139+
//////////////
140+
141+
// npm run development -- --env.run html
142+
if (__RUN === 'html' || !__RUN) {
143+
for (let file of glob.sync('./src/html/pages/*.html', { ignore: '**/_*' })) {
144+
Mix.entry().entry.add('mix', path.resolve(file))
145+
}
146+
147+
webpackConfig = merge(webpackConfig, {
148+
module: {
149+
rules: [{
150+
test: /\.html$/,
151+
loaders: [{
152+
loader: 'file-loader',
153+
options: {
154+
name: 'dist/[path][name].html',
155+
context: './src/html/pages',
156+
useRelativePath: true
157+
}
158+
}, 'jsbeautify-loader', {
159+
loader: 'nunjucks-html-loader',
160+
options: {
161+
searchPaths: [
162+
'./src/html'
163+
]
164+
}
165+
}, 'front-matter-loader']
166+
}]
167+
}
168+
})
169+
}
170+
171+
//////////////////
172+
// APPLY CONFIG //
173+
//////////////////
174+
175+
mix.webpackConfig(webpackConfig)
176+
177+
/////////////////
178+
// BROWSERSYNC //
179+
/////////////////
180+
181+
if (!__RUN) {
182+
mix.browserSync(require('./bs-config.json'))
183+
}

0 commit comments

Comments
 (0)