mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
chore: wip
This commit is contained in:
parent
daaa8eda8c
commit
dc84429d67
@ -1,4 +1,5 @@
|
||||
import { resolve } from 'path'
|
||||
import { createWatcher } from './watch'
|
||||
|
||||
export interface NuxtRoute {
|
||||
path: ''
|
||||
|
@ -1,11 +1,15 @@
|
||||
import { join } from 'path'
|
||||
import fsExtra from 'fs-extra'
|
||||
import { BundleBuilder } from 'src/webpack'
|
||||
import { Nuxt } from '../core'
|
||||
import { copyTemplates } from './template'
|
||||
import { compileTemplates, scanTemplates, NuxtTemplate } from './template'
|
||||
import { createWatcher } from './watch'
|
||||
import { resolveApp, NuxtApp } from './app'
|
||||
|
||||
export class Builder {
|
||||
nuxt: Nuxt
|
||||
app: NuxtApp
|
||||
templates: NuxtTemplate[]
|
||||
|
||||
constructor (nuxt) {
|
||||
this.nuxt = nuxt
|
||||
@ -17,15 +21,64 @@ export class Builder {
|
||||
}
|
||||
|
||||
// Extends VueRouter
|
||||
async function build (builder: Builder) {
|
||||
async function build(builder: Builder) {
|
||||
const { nuxt } = builder
|
||||
|
||||
builder.app = resolveApp(nuxt, nuxt.options.srcDir)
|
||||
await copyTemplates(builder)
|
||||
await generate(builder)
|
||||
|
||||
if (nuxt.options.dev) {
|
||||
watch(builder)
|
||||
}
|
||||
|
||||
await bundle(builder)
|
||||
}
|
||||
|
||||
function watch(builder: Builder) {
|
||||
const { nuxt } = builder
|
||||
|
||||
// Watch internal templates
|
||||
const nuxtAppWatcher = createWatcher(nuxt.options.appDir)
|
||||
// nuxtAppWatcher.debug()
|
||||
nuxtAppWatcher.watchAll(async () => {
|
||||
console.log('Re-generate templates')
|
||||
await compileTemplates(builder.templates, nuxt.options.buildDir)
|
||||
})
|
||||
|
||||
// Watch user app
|
||||
const appWatcher = createWatcher(builder.app.srcDir, {
|
||||
ignored: [
|
||||
nuxt.options.buildDir
|
||||
]
|
||||
})
|
||||
// appWatcher.debug()
|
||||
appWatcher.watch(/(A|a)pp\.[a-z]{2,3}/, async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 200))
|
||||
await generate(builder)
|
||||
})
|
||||
appWatcher.watch('pages/', async () => {
|
||||
console.log('Re-generate routes')
|
||||
await compileTemplates(builder.templates, nuxt.options.buildDir)
|
||||
})
|
||||
}
|
||||
|
||||
export async function generate(builder: Builder) {
|
||||
const { nuxt } = builder
|
||||
|
||||
await fsExtra.mkdirp(nuxt.options.buildDir)
|
||||
builder.app = resolveApp(nuxt, nuxt.options.srcDir)
|
||||
|
||||
const templatesDir = join(builder.nuxt.options.appDir, '_templates')
|
||||
const appTemplates = await scanTemplates(templatesDir, {
|
||||
app: builder.app
|
||||
})
|
||||
|
||||
builder.templates = [
|
||||
...appTemplates
|
||||
]
|
||||
|
||||
await compileTemplates(builder.templates, nuxt.options.buildDir)
|
||||
}
|
||||
|
||||
async function bundle ({ nuxt }: Builder) {
|
||||
// TODO: get rid of this context and directly pass nuxt to BundleBuilder
|
||||
const bundleBuilder = new BundleBuilder({
|
||||
|
@ -1,26 +1,40 @@
|
||||
import { resolve, join, sep } from 'path'
|
||||
import { join, relative, dirname } from 'path'
|
||||
import fsExtra from 'fs-extra'
|
||||
import globby from 'globby'
|
||||
import lodashTemplate from 'lodash/template'
|
||||
import { Builder } from './builder'
|
||||
|
||||
export async function copyTemplates ({ nuxt, app }: Builder) {
|
||||
// Resolve appDir
|
||||
const templatesDir = join(nuxt.options.appDir, '_templates')
|
||||
|
||||
const templateFiles = (await globby(join(templatesDir, '/**')))
|
||||
.map(f => f.replace(templatesDir + sep, ''))
|
||||
|
||||
await fsExtra.mkdirp(nuxt.options.buildDir)
|
||||
|
||||
for (const template of templateFiles) {
|
||||
const src = resolve(templatesDir, template)
|
||||
const dst = resolve(nuxt.options.buildDir, template)
|
||||
|
||||
const templateData = { app: Object.freeze(app) }
|
||||
const srcContents = await fsExtra.readFile(src, 'utf-8')
|
||||
const compiledSrc = lodashTemplate(srcContents, {})(templateData)
|
||||
|
||||
await fsExtra.writeFile(dst, compiledSrc)
|
||||
}
|
||||
interface NuxtTemplate {
|
||||
src: string // Absolute path to source file
|
||||
path: string // Relative path of destination
|
||||
data?: any
|
||||
}
|
||||
|
||||
async function compileTemplate({ src, path, data }: NuxtTemplate, destDir: string) {
|
||||
const srcContents = await fsExtra.readFile(src, 'utf-8')
|
||||
const compiledSrc = lodashTemplate(srcContents, {})(data)
|
||||
const dest = join(destDir, path)
|
||||
console.log('Compile template', dest)
|
||||
await fsExtra.mkdirp(dirname(dest))
|
||||
await fsExtra.writeFile(dest, compiledSrc)
|
||||
}
|
||||
|
||||
export async function compileTemplates(templates: NuxtTemplate[], destDir: string) {
|
||||
return Promise.all(templates.map(t => compileTemplate(t, destDir)))
|
||||
}
|
||||
|
||||
export async function scanTemplates (dir: string, data?: Object) {
|
||||
const templateFiles = (await globby(join(dir, '/**')))
|
||||
|
||||
return templateFiles.map(src => ({
|
||||
src,
|
||||
path: relative(dir, src),
|
||||
data
|
||||
}))
|
||||
}
|
||||
|
||||
export async function watchTemplate(template: NuxtTemplate, watcher: any, cb: Function) {
|
||||
template.data = new Proxy(template.data, {
|
||||
// TODO: deep watch option changes
|
||||
})
|
||||
// TODO: Watch fs changes
|
||||
}
|
||||
|
40
packages/nuxt3/src/builder/watch.ts
Normal file
40
packages/nuxt3/src/builder/watch.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import chokidar, { WatchOptions } from 'chokidar'
|
||||
import { relative } from 'path'
|
||||
|
||||
export function createWatcher(dir: string|string[], options?: WatchOptions) {
|
||||
const watcher = chokidar.watch(dir, {
|
||||
ignored: [],
|
||||
ignoreInitial: true,
|
||||
...options
|
||||
})
|
||||
|
||||
const watchAll = (cb: Function, filter?: Function) => {
|
||||
watcher.on('raw', (event, path: string, details) => {
|
||||
if (options.ignored.find(ignore => path.match(ignore))) {
|
||||
return // 🖕 chokidar ignored option
|
||||
}
|
||||
path = relative(dir, path)
|
||||
const _event = { event, path }
|
||||
if (!filter || filter(_event)) {
|
||||
cb(_event)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const watch = (pattern: string| RegExp, cb: Function) => watchAll(cb, e => e.path.match(pattern))
|
||||
|
||||
const debug = (tag: string = '[Watcher]') => {
|
||||
console.log(tag, 'Watching ', dir)
|
||||
watchAll((e) => {
|
||||
console.log(tag, e.event, e.path)
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
watchAll,
|
||||
watch,
|
||||
debug
|
||||
}
|
||||
}
|
||||
|
||||
export type Watcher = ReturnType<typeof createWatcher>
|
@ -4,7 +4,8 @@ import TimeFixPlugin from 'time-fix-plugin'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import escapeRegExp from 'lodash/escapeRegExp'
|
||||
import VueLoaderPlugin from 'vue-loader/dist/pluginWebpack5'
|
||||
import ExtractCssChunksPlugin from 'extract-css-chunks-webpack-plugin'
|
||||
// import ExtractCssChunksPlugin from 'extract-css-chunks-webpack-plugin'
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
|
||||
import TerserWebpackPlugin from 'terser-webpack-plugin'
|
||||
import WebpackBar from 'webpackbar'
|
||||
import env from 'std-env'
|
||||
@ -398,7 +399,7 @@ export default class WebpackBaseConfig {
|
||||
|
||||
// CSS extraction)
|
||||
if (buildOptions.extractCSS) {
|
||||
plugins.push(new ExtractCssChunksPlugin(Object.assign({
|
||||
plugins.push(new MiniCssExtractPlugin(Object.assign({
|
||||
filename: this.getFileName('css'),
|
||||
chunkFilename: this.getFileName('css')
|
||||
}, buildOptions.extractCSS)))
|
||||
@ -446,7 +447,7 @@ export default class WebpackBaseConfig {
|
||||
|
||||
// CSS extraction
|
||||
if (this.buildContext.buildOptions.extractCSS) {
|
||||
plugins.push(new ExtractCssChunksPlugin(Object.assign({
|
||||
plugins.push(new MiniCssExtractPlugin(Object.assign({
|
||||
filename: this.getFileName('css'),
|
||||
chunkFilename: this.getFileName('css'),
|
||||
// TODO: https://github.com/faceyspacey/extract-css-chunks-webpack-plugin/issues/132
|
||||
|
@ -1,5 +1,6 @@
|
||||
import path from 'path'
|
||||
import ExtractCssChunksPlugin from 'extract-css-chunks-webpack-plugin'
|
||||
// import ExtractCssChunksPlugin from 'extract-css-chunks-webpack-plugin'
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
|
||||
|
||||
import { wrapArray } from 'src/utils'
|
||||
|
||||
@ -20,8 +21,9 @@ export default class StyleLoader {
|
||||
return this.buildContext.buildOptions.extractCSS
|
||||
}
|
||||
|
||||
get onlyLocals () {
|
||||
return Boolean(this.isServer && this.extractCSS)
|
||||
get onlyLocals() {
|
||||
// Not supported anymore by css-loader
|
||||
return false // Boolean(this.isServer && this.extractCSS)
|
||||
}
|
||||
|
||||
normalize (loaders) {
|
||||
@ -86,7 +88,7 @@ export default class StyleLoader {
|
||||
if (this.extractCSS) {
|
||||
const isDev = this.buildContext.options.dev
|
||||
return {
|
||||
loader: ExtractCssChunksPlugin.loader,
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: {
|
||||
// TODO: https://github.com/faceyspacey/extract-css-chunks-webpack-plugin/issues/132
|
||||
// https://github.com/faceyspacey/extract-css-chunks-webpack-plugin/issues/161#issuecomment-500162574
|
||||
|
Loading…
Reference in New Issue
Block a user