diff --git a/src/config/webpack.serve.loader.js b/src/config/webpack.serve.loader.js index e06f090..7482e79 100644 --- a/src/config/webpack.serve.loader.js +++ b/src/config/webpack.serve.loader.js @@ -4,11 +4,18 @@ * @module config/webpack.serve.loader */ +import fs from 'fs'; +import path from 'path'; import { pRequire, getContext } from '..'; import getExistConfigPath from '../lib/get-exist-config-path'; const context = getContext(); +const babelOptions = {}; +if (context && fs.existsSync(path.resolve(context, 'babel.config.js'))) { + babelOptions.cwd = context; +} + const { assetExtensions, cssLoader: cssLoaderOptions, @@ -26,7 +33,8 @@ const postcssLoaderOptions = { const jsLoaders = [ { - loader: 'babel-loader' + loader: 'babel-loader', + options: babelOptions } ]; diff --git a/test/cases/packing-dll/package.json b/test/cases/packing-dll/package.json index 8980c96..868ddce 100644 --- a/test/cases/packing-dll/package.json +++ b/test/cases/packing-dll/package.json @@ -1,9 +1,9 @@ { - "dependencies": { - "a": "^8.13" - }, - "devDependencies": { - "b": "^1.3.2", - "c": "^1.18.2" - } - } \ No newline at end of file + "dependencies": { + "a": "^8.13" + }, + "devDependencies": { + "b": "^1.3.2", + "c": "^1.18.2" + } +} diff --git a/test/cases/typescript/.eslintrc.js b/test/cases/typescript/.eslintrc.js new file mode 100644 index 0000000..3487726 --- /dev/null +++ b/test/cases/typescript/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + extends: [ + 'eslint-config-qunar-typescript-base' + ] +}; diff --git a/test/cases/typescript/babel.config.js b/test/cases/typescript/babel.config.js new file mode 100644 index 0000000..373895e --- /dev/null +++ b/test/cases/typescript/babel.config.js @@ -0,0 +1,55 @@ +module.exports = { + presets: [ + [ + '@babel/preset-env', + { + useBuiltIns: 'usage', + targets: { + browsers: [ + '> 1%', + 'Android >= 4.4', + 'IOS >= 7', + 'ie >= 10' + ] + } + } + ], + '@babel/typescript' + ], + plugins: [ + [ + '@babel/plugin-transform-runtime', + { + helpers: false, + regenerator: true + } + ], + 'add-module-exports', + [ + '@babel/plugin-proposal-decorators', + { + legacy: true + } + ], + '@babel/plugin-syntax-dynamic-import', + '@babel/plugin-syntax-import-meta', + '@babel/plugin-proposal-class-properties', + '@babel/plugin-proposal-json-strings', + '@babel/plugin-proposal-function-sent', + '@babel/plugin-proposal-export-namespace-from', + '@babel/plugin-proposal-numeric-separator', + '@babel/plugin-proposal-throw-expressions', + '@babel/plugin-proposal-export-default-from', + '@babel/plugin-proposal-logical-assignment-operators', + '@babel/plugin-proposal-optional-chaining', + [ + '@babel/plugin-proposal-pipeline-operator', + { + proposal: 'minimal' + } + ], + '@babel/plugin-proposal-nullish-coalescing-operator', + '@babel/plugin-proposal-do-expressions', + '@babel/plugin-proposal-function-bind' + ] +}; diff --git a/test/cases/typescript/config/webpack.build.babel.js b/test/cases/typescript/config/webpack.build.babel.js new file mode 100644 index 0000000..d6ca9cf --- /dev/null +++ b/test/cases/typescript/config/webpack.build.babel.js @@ -0,0 +1,32 @@ +/** + * 这个文件可以修改build的默认设置 + * 默认配置请看 `node_modules/packing/config/webpack.build.babel.js` + * + * @param object webpackConfig 默认配置对象 + * @param object program packing-cli程序对象 + * @param object appConfig config/packing.js中的配置 + */ + +export default (webpackConfig/* , program, appConfig */) => { + const config = webpackConfig; + + // babel-loader 中增加对 .ts 的匹配 + const [jsloader] = config.module.rules; + jsloader.test = /\.(t|j)sx?$/i; + + // 设置文件扩展名,支持 .ts + config.resolve.extensions = ['.js', '.ts']; + + // webpackConfig 为系统默认的webpack配置,此处可以根据项目情况修改 + // 修改 entry + // config.entry = 'xxx/xxx.js'; + // 修改 plugins(修改 = 先删除现有的,再添加新的) + // config.plugins = config.plugins.filter(plugin => !(plugin.filename && plugin.id)); + // config.plugins.push( + // new ExtractTextPlugin({ + // filename: '[name]-[contenthash:8].css', + // allChunks: true + // }) + // ) + return config; +}; diff --git a/test/cases/typescript/config/webpack.serve.babel.js b/test/cases/typescript/config/webpack.serve.babel.js new file mode 100644 index 0000000..320e781 --- /dev/null +++ b/test/cases/typescript/config/webpack.serve.babel.js @@ -0,0 +1,32 @@ +/** + * 这个文件可以修改serve的默认设置 + * 默认配置请看 `node_modules/packing/config/webpack.serve.babel.js` + * + * @param object webpackConfig 默认配置对象 + * @param object program packing-cli程序对象 + * @param object appConfig config/packing.js中的配置 + */ + +export default (webpackConfig/* , program, appConfig */) => { + const config = webpackConfig; + + // babel-loader 中增加对 .ts 的匹配 + const [jsloader] = config.module.rules; + jsloader.test = /\.(t|j)sx?$/i; + + // 设置文件扩展名,支持 .ts + config.resolve.extensions = ['.js', '.ts']; + + // webpackConfig 为系统默认的webpack配置,此处可以根据项目情况修改 + // 修改 entry + // config.entry = 'xxx/xxx.js'; + // 修改 plugins(修改 = 先删除现有的,再添加新的) + // config.plugins = config.plugins.filter(plugin => !(plugin.filename && plugin.id)); + // config.plugins.push( + // new ExtractTextPlugin({ + // filename: '[name]-[contenthash:8].css', + // allChunks: true + // }) + // ) + return config; +}; diff --git a/test/cases/typescript/index.js b/test/cases/typescript/index.js new file mode 100644 index 0000000..adb397e --- /dev/null +++ b/test/cases/typescript/index.js @@ -0,0 +1,7 @@ +process.env.CONTEXT = __dirname; + +const { getTestCaseName } = require('../../util'); + +describe(getTestCaseName(), async () => { + require('./test'); +}); diff --git a/test/cases/typescript/package.json b/test/cases/typescript/package.json new file mode 100644 index 0000000..ad4da7f --- /dev/null +++ b/test/cases/typescript/package.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "@babel/preset-typescript": "^7.6.0", + "eslint-config-qunar-typescript-base": "1.0.2", + "typescript": "^3.6.4" + } +} diff --git a/test/cases/typescript/src/pages/index/a.ts b/test/cases/typescript/src/pages/index/a.ts new file mode 100644 index 0000000..d369319 --- /dev/null +++ b/test/cases/typescript/src/pages/index/a.ts @@ -0,0 +1,3 @@ +const a: string = 'a'; + +export default a; diff --git a/test/cases/typescript/src/pages/index/entry.js b/test/cases/typescript/src/pages/index/entry.js new file mode 100644 index 0000000..4de7545 --- /dev/null +++ b/test/cases/typescript/src/pages/index/entry.js @@ -0,0 +1,3 @@ +import a from './a'; + +console.log(a); diff --git a/test/cases/typescript/src/pages/index/entry.settings.js b/test/cases/typescript/src/pages/index/entry.settings.js new file mode 100644 index 0000000..2a7f9af --- /dev/null +++ b/test/cases/typescript/src/pages/index/entry.settings.js @@ -0,0 +1,6 @@ +export default { + title: '首页', + // 以下变量供自定义模版变量替换使用,自定义模版变量格式为 __var__ + name: 'Packing', + me: '🐶' +}; diff --git a/test/cases/typescript/src/templates/layout/default.pug b/test/cases/typescript/src/templates/layout/default.pug new file mode 100644 index 0000000..5567833 --- /dev/null +++ b/test/cases/typescript/src/templates/layout/default.pug @@ -0,0 +1,15 @@ +doctype html +html + head + block meta + meta(http-equiv="Content-Type" content="text/html;charset=utf-8") + meta(content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport") + meta(name="apple-mobile-web-app-capable" content="yes") + meta(name="apple-mobile-web-app-status-bar-style" content="black") + meta(content="telephone=no" name="format-detection") + block title + title Default title + block style + body + block content + block script diff --git a/test/cases/typescript/src/templates/pages/default.pug b/test/cases/typescript/src/templates/pages/default.pug new file mode 100644 index 0000000..5a38797 --- /dev/null +++ b/test/cases/typescript/src/templates/pages/default.pug @@ -0,0 +1,10 @@ +extends /layout/default.pug + +block content + h1 Hello, #{name} + h2 #{me} + ul + li + a(href="/") Home + li + a(href="/about") About diff --git a/test/cases/typescript/test.js b/test/cases/typescript/test.js new file mode 100644 index 0000000..528cd46 --- /dev/null +++ b/test/cases/typescript/test.js @@ -0,0 +1,50 @@ +import { resolve } from 'path'; +import request from 'supertest'; +import webpack from 'webpack'; +import Express from 'express'; +import webpackDevMiddleware from 'webpack-dev-middleware'; +import urlrewrite from 'packing-urlrewrite'; +import '../../../src'; +import { pRequire, middleware, getContext } from '../../../src'; + +describe(getTestCaseName(), async () => { + let app; + before(() => { + const context = getContext(); + const appConfig = pRequire('config/packing'); + const webpackConfig = pRequire('config/webpack.serve.babel', {}, appConfig); + + const mwOptions = process.env.DEBUG ? { + serverSideRender: true + } : { + serverSideRender: true, + // 禁止 webpack-dev-middleware 输出日志 + logger: { + info: () => {}, + error: console.log + } + }; + + app = new Express(); + app.use(Express.static(resolve(context, appConfig.path.tmpDll))); + const compiler = webpack(webpackConfig); + const webpackDevMiddlewareInstance = webpackDevMiddleware(compiler, mwOptions); + webpackDevMiddlewareInstance.waitUntilValid(async () => { + app.use(urlrewrite(appConfig.rewriteRules)); + middleware(app, appConfig); + }); + app.use(webpackDevMiddlewareInstance); + }); + + describe('/', async () => { + let res; + before(async () => { + res = await request(app.listen()).get('/index'); + console.log(res.text); + }); + + it('应该正常返回网页', async () => { + res.status.should.eql(200); + }); + }); +}); diff --git a/test/cases/typescript/tsconfig.json b/test/cases/typescript/tsconfig.json new file mode 100644 index 0000000..e672a8c --- /dev/null +++ b/test/cases/typescript/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "module": "commonjs", + "esModuleInterop": true, + "target": "es5", + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./src", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "lib": [ + "es2017", + "dom" + ] + }, + "exclude": [ + "node_modules" + ] +} diff --git a/test/index.js b/test/index.js index 16f675e..9eebfb0 100644 --- a/test/index.js +++ b/test/index.js @@ -2,6 +2,7 @@ const cp = require('child_process'); const chalk = require('chalk'); const glob = require('glob'); const path = require('path'); +const fs = require('fs'); process.env.NODE_ENV = process.env.NODE_ENV || 'local'; @@ -13,6 +14,26 @@ files.forEach((file, i) => { const cmd = `node_modules/.bin/mocha test/${file}`; const title = `[${i + 1}/${files.length}] ${cmd}`; console.log(chalk.yellow(title)); + + // 是否需要安装依赖 + const packagePath = path.resolve(path.dirname(`./test/${file}`), 'package.json'); + if (fs.existsSync(packagePath)) { + const { dependencies } = require(packagePath); + if (dependencies && Object.keys(dependencies).length > 0) { + let npm = 'npm i --registry https://registry.npm.taobao.org --no-save'; + + Object.keys(dependencies).forEach((key) => { + npm = `${npm} ${key}@${dependencies[key]}`; + }); + // console.log(npm); + try { + cp.execSync(npm, { encoding: 'utf-8' }); + } catch (e) { + // npm install failed. + } + } + } + try { const stdout = cp.execSync(cmd, { encoding: 'utf-8' }); console.log(stdout);