first
This commit is contained in:
99
build/bin/build-entry.js
Normal file
99
build/bin/build-entry.js
Normal file
@@ -0,0 +1,99 @@
|
||||
var Components = require('../../components.json');
|
||||
var fs = require('fs');
|
||||
var render = require('json-templater/string');
|
||||
var uppercamelcase = require('uppercamelcase');
|
||||
var path = require('path');
|
||||
var endOfLine = require('os').EOL;
|
||||
|
||||
var OUTPUT_PATH = path.join(__dirname, '../../src/index.js');
|
||||
var IMPORT_TEMPLATE = 'import {{name}} from \'../packages/{{package}}/index.js\';';
|
||||
var INSTALL_COMPONENT_TEMPLATE = ' {{name}}';
|
||||
var MAIN_TEMPLATE = `/* Automatically generated by './build/bin/build-entry.js' */
|
||||
|
||||
{{include}}
|
||||
import locale from 'element-ui/src/locale';
|
||||
import CollapseTransition from 'element-ui/src/transitions/collapse-transition';
|
||||
|
||||
const components = [
|
||||
{{install}},
|
||||
CollapseTransition
|
||||
];
|
||||
|
||||
const install = function(Vue, opts = {}) {
|
||||
locale.use(opts.locale);
|
||||
locale.i18n(opts.i18n);
|
||||
|
||||
components.forEach(component => {
|
||||
Vue.component(component.name, component);
|
||||
});
|
||||
|
||||
Vue.use(InfiniteScroll);
|
||||
Vue.use(Loading.directive);
|
||||
|
||||
Vue.prototype.$ELEMENT = {
|
||||
size: opts.size || '',
|
||||
zIndex: opts.zIndex || 2000
|
||||
};
|
||||
|
||||
Vue.prototype.$loading = Loading.service;
|
||||
Vue.prototype.$msgbox = MessageBox;
|
||||
Vue.prototype.$alert = MessageBox.alert;
|
||||
Vue.prototype.$confirm = MessageBox.confirm;
|
||||
Vue.prototype.$prompt = MessageBox.prompt;
|
||||
Vue.prototype.$notify = Notification;
|
||||
Vue.prototype.$message = Message;
|
||||
|
||||
};
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (typeof window !== 'undefined' && window.Vue) {
|
||||
install(window.Vue);
|
||||
}
|
||||
|
||||
export default {
|
||||
version: '{{version}}',
|
||||
locale: locale.use,
|
||||
i18n: locale.i18n,
|
||||
install,
|
||||
CollapseTransition,
|
||||
Loading,
|
||||
{{list}}
|
||||
};
|
||||
`;
|
||||
|
||||
delete Components.font;
|
||||
|
||||
var ComponentNames = Object.keys(Components);
|
||||
|
||||
var includeComponentTemplate = [];
|
||||
var installTemplate = [];
|
||||
var listTemplate = [];
|
||||
|
||||
ComponentNames.forEach(name => {
|
||||
var componentName = uppercamelcase(name);
|
||||
|
||||
includeComponentTemplate.push(render(IMPORT_TEMPLATE, {
|
||||
name: componentName,
|
||||
package: name
|
||||
}));
|
||||
|
||||
if (['Loading', 'MessageBox', 'Notification', 'Message', 'InfiniteScroll'].indexOf(componentName) === -1) {
|
||||
installTemplate.push(render(INSTALL_COMPONENT_TEMPLATE, {
|
||||
name: componentName,
|
||||
component: name
|
||||
}));
|
||||
}
|
||||
|
||||
if (componentName !== 'Loading') listTemplate.push(` ${componentName}`);
|
||||
});
|
||||
|
||||
var template = render(MAIN_TEMPLATE, {
|
||||
include: includeComponentTemplate.join(endOfLine),
|
||||
install: installTemplate.join(',' + endOfLine),
|
||||
version: process.env.VERSION || require('../../package.json').version,
|
||||
list: listTemplate.join(',' + endOfLine)
|
||||
});
|
||||
|
||||
fs.writeFileSync(OUTPUT_PATH, template);
|
||||
console.log('[build entry] DONE:', OUTPUT_PATH);
|
||||
|
39
build/bin/build-locale.js
Normal file
39
build/bin/build-locale.js
Normal file
@@ -0,0 +1,39 @@
|
||||
var fs = require('fs');
|
||||
var save = require('file-save');
|
||||
var resolve = require('path').resolve;
|
||||
var basename = require('path').basename;
|
||||
var localePath = resolve(__dirname, '../../src/locale/lang');
|
||||
var fileList = fs.readdirSync(localePath);
|
||||
|
||||
var transform = function(filename, name, cb) {
|
||||
require('babel-core').transformFile(resolve(localePath, filename), {
|
||||
plugins: [
|
||||
'add-module-exports',
|
||||
['transform-es2015-modules-umd', {loose: true}]
|
||||
],
|
||||
moduleId: name
|
||||
}, cb);
|
||||
};
|
||||
|
||||
fileList
|
||||
.filter(function(file) {
|
||||
return /\.js$/.test(file);
|
||||
})
|
||||
.forEach(function(file) {
|
||||
var name = basename(file, '.js');
|
||||
|
||||
transform(file, name, function(err, result) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
} else {
|
||||
var code = result.code;
|
||||
|
||||
code = code
|
||||
.replace('define(\'', 'define(\'element/locale/')
|
||||
.replace('global.', 'global.ELEMENT.lang = global.ELEMENT.lang || {}; \n global.ELEMENT.lang.');
|
||||
save(resolve(__dirname, '../../lib/umd/locale', file)).write(code);
|
||||
|
||||
console.log(file);
|
||||
}
|
||||
});
|
||||
});
|
32
build/bin/gen-cssfile.js
Normal file
32
build/bin/gen-cssfile.js
Normal file
@@ -0,0 +1,32 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var Components = require('../../components.json');
|
||||
var themes = [
|
||||
'theme-chalk'
|
||||
];
|
||||
Components = Object.keys(Components);
|
||||
var basepath = path.resolve(__dirname, '../../packages/');
|
||||
|
||||
function fileExists(filePath) {
|
||||
try {
|
||||
return fs.statSync(filePath).isFile();
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
themes.forEach((theme) => {
|
||||
var isSCSS = theme !== 'theme-default';
|
||||
var indexContent = isSCSS ? '@import "./base.scss";\n' : '@import "./base.css";\n';
|
||||
Components.forEach(function(key) {
|
||||
if (['icon', 'option', 'option-group'].indexOf(key) > -1) return;
|
||||
var fileName = key + (isSCSS ? '.scss' : '.css');
|
||||
indexContent += '@import "./' + fileName + '";\n';
|
||||
var filePath = path.resolve(basepath, theme, 'src', fileName);
|
||||
if (!fileExists(filePath)) {
|
||||
fs.writeFileSync(filePath, '', 'utf8');
|
||||
console.log(theme, ' 创建遗漏的 ', fileName, ' 文件');
|
||||
}
|
||||
});
|
||||
fs.writeFileSync(path.resolve(basepath, theme, 'src', isSCSS ? 'index.scss' : 'index.css'), indexContent);
|
||||
});
|
58
build/bin/gen-indices.js
Normal file
58
build/bin/gen-indices.js
Normal file
@@ -0,0 +1,58 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const algoliasearch = require('algoliasearch');
|
||||
const slugify = require('transliteration').slugify;
|
||||
const key = require('./algolia-key');
|
||||
|
||||
const client = algoliasearch('4C63BTGP6S', key);
|
||||
const langs = {
|
||||
'zh-CN': 'element-zh',
|
||||
'en-US': 'element-en',
|
||||
'es': 'element-es',
|
||||
'fr-FR': 'element-fr'
|
||||
};
|
||||
|
||||
['zh-CN', 'en-US', 'es', 'fr-FR'].forEach(lang => {
|
||||
const indexName = langs[lang];
|
||||
const index = client.initIndex(indexName);
|
||||
index.clearIndex(err => {
|
||||
if (err) return;
|
||||
fs.readdir(path.resolve(__dirname, `../../examples/docs/${ lang }`), (err, files) => {
|
||||
if (err) return;
|
||||
let indices = [];
|
||||
files.forEach(file => {
|
||||
const component = file.replace('.md', '');
|
||||
const content = fs.readFileSync(path.resolve(__dirname, `../../examples/docs/${ lang }/${ file }`), 'utf8');
|
||||
const matches = content
|
||||
.replace(/:::[\s\S]*?:::/g, '')
|
||||
.replace(/```[\s\S]*?```/g, '')
|
||||
.match(/#{2,4}[^#]*/g)
|
||||
.map(match => match.replace(/\n+/g, '\n').split('\n').filter(part => !!part))
|
||||
.map(match => {
|
||||
const length = match.length;
|
||||
if (length > 2) {
|
||||
const desc = match.slice(1, length).join('');
|
||||
return [match[0], desc];
|
||||
}
|
||||
return match;
|
||||
});
|
||||
|
||||
indices = indices.concat(matches.map(match => {
|
||||
const isComponent = match[0].indexOf('###') < 0;
|
||||
const title = match[0].replace(/#{2,4}/, '').trim();
|
||||
const index = { component, title };
|
||||
index.ranking = isComponent ? 2 : 1;
|
||||
index.anchor = slugify(title);
|
||||
index.content = (match[1] || title).replace(/<[^>]+>/g, '');
|
||||
return index;
|
||||
}));
|
||||
});
|
||||
|
||||
index.addObjects(indices, (err, res) => {
|
||||
console.log(err, res);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
26
build/bin/i18n.js
Normal file
26
build/bin/i18n.js
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var langConfig = require('../../examples/i18n/page.json');
|
||||
|
||||
langConfig.forEach(lang => {
|
||||
try {
|
||||
fs.statSync(path.resolve(__dirname, `../../examples/pages/${ lang.lang }`));
|
||||
} catch (e) {
|
||||
fs.mkdirSync(path.resolve(__dirname, `../../examples/pages/${ lang.lang }`));
|
||||
}
|
||||
|
||||
Object.keys(lang.pages).forEach(page => {
|
||||
var templatePath = path.resolve(__dirname, `../../examples/pages/template/${ page }.tpl`);
|
||||
var outputPath = path.resolve(__dirname, `../../examples/pages/${ lang.lang }/${ page }.vue`);
|
||||
var content = fs.readFileSync(templatePath, 'utf8');
|
||||
var pairs = lang.pages[page];
|
||||
|
||||
Object.keys(pairs).forEach(key => {
|
||||
content = content.replace(new RegExp(`<%=\\s*${ key }\\s*>`, 'g'), pairs[key]);
|
||||
});
|
||||
|
||||
fs.writeFileSync(outputPath, content);
|
||||
});
|
||||
});
|
22
build/bin/iconInit.js
Normal file
22
build/bin/iconInit.js
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
var postcss = require('postcss');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var fontFile = fs.readFileSync(path.resolve(__dirname, '../../packages/theme-chalk/src/icon.scss'), 'utf8');
|
||||
var nodes = postcss.parse(fontFile).nodes;
|
||||
var classList = [];
|
||||
|
||||
nodes.forEach((node) => {
|
||||
var selector = node.selector || '';
|
||||
var reg = new RegExp(/\.el-icon-([^:]+):before/);
|
||||
var arr = selector.match(reg);
|
||||
|
||||
if (arr && arr[1]) {
|
||||
classList.push(arr[1]);
|
||||
}
|
||||
});
|
||||
|
||||
classList.reverse(); // 希望按 css 文件顺序倒序排列
|
||||
|
||||
fs.writeFile(path.resolve(__dirname, '../../examples/icon.json'), JSON.stringify(classList), () => {});
|
60
build/bin/new-lang.js
Normal file
60
build/bin/new-lang.js
Normal file
@@ -0,0 +1,60 @@
|
||||
'use strict';
|
||||
|
||||
console.log();
|
||||
process.on('exit', () => {
|
||||
console.log();
|
||||
});
|
||||
|
||||
if (!process.argv[2]) {
|
||||
console.error('[language] is required!');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var fs = require('fs');
|
||||
const path = require('path');
|
||||
const fileSave = require('file-save');
|
||||
const lang = process.argv[2];
|
||||
// const configPath = path.resolve(__dirname, '../../examples/i18n', lang);
|
||||
|
||||
// 添加到 components.json
|
||||
const componentFile = require('../../examples/i18n/component.json');
|
||||
if (componentFile.some(item => item.lang === lang)) {
|
||||
console.error(`${lang} already exists.`);
|
||||
process.exit(1);
|
||||
}
|
||||
let componentNew = Object.assign({}, componentFile.filter(item => item.lang === 'en-US')[0], { lang });
|
||||
componentFile.push(componentNew);
|
||||
fileSave(path.join(__dirname, '../../examples/i18n/component.json'))
|
||||
.write(JSON.stringify(componentFile, null, ' '), 'utf8')
|
||||
.end('\n');
|
||||
|
||||
// 添加到 page.json
|
||||
const pageFile = require('../../examples/i18n/page.json');
|
||||
let pageNew = Object.assign({}, pageFile.filter(item => item.lang === 'en-US')[0], { lang });
|
||||
pageFile.push(pageNew);
|
||||
fileSave(path.join(__dirname, '../../examples/i18n/page.json'))
|
||||
.write(JSON.stringify(pageFile, null, ' '), 'utf8')
|
||||
.end('\n');
|
||||
|
||||
// 添加到 route.json
|
||||
const routeFile = require('../../examples/i18n/route.json');
|
||||
routeFile.push({ lang });
|
||||
fileSave(path.join(__dirname, '../../examples/i18n/route.json'))
|
||||
.write(JSON.stringify(routeFile, null, ' '), 'utf8')
|
||||
.end('\n');
|
||||
|
||||
// 添加到 nav.config.json
|
||||
const navFile = require('../../examples/nav.config.json');
|
||||
navFile[lang] = navFile['en-US'];
|
||||
fileSave(path.join(__dirname, '../../examples/nav.config.json'))
|
||||
.write(JSON.stringify(navFile, null, ' '), 'utf8')
|
||||
.end('\n');
|
||||
|
||||
// docs 下新建对应文件夹
|
||||
try {
|
||||
fs.statSync(path.resolve(__dirname, `../../examples/docs/${ lang }`));
|
||||
} catch (e) {
|
||||
fs.mkdirSync(path.resolve(__dirname, `../../examples/docs/${ lang }`));
|
||||
}
|
||||
|
||||
console.log('DONE!');
|
155
build/bin/new.js
Normal file
155
build/bin/new.js
Normal file
@@ -0,0 +1,155 @@
|
||||
'use strict';
|
||||
|
||||
console.log();
|
||||
process.on('exit', () => {
|
||||
console.log();
|
||||
});
|
||||
|
||||
if (!process.argv[2]) {
|
||||
console.error('[组件名]必填 - Please enter new component name');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const fileSave = require('file-save');
|
||||
const uppercamelcase = require('uppercamelcase');
|
||||
const componentname = process.argv[2];
|
||||
const chineseName = process.argv[3] || componentname;
|
||||
const ComponentName = uppercamelcase(componentname);
|
||||
const PackagePath = path.resolve(__dirname, '../../packages', componentname);
|
||||
const Files = [
|
||||
{
|
||||
filename: 'index.js',
|
||||
content: `import ${ComponentName} from './src/main';
|
||||
|
||||
/* istanbul ignore next */
|
||||
${ComponentName}.install = function(Vue) {
|
||||
Vue.component(${ComponentName}.name, ${ComponentName});
|
||||
};
|
||||
|
||||
export default ${ComponentName};`
|
||||
},
|
||||
{
|
||||
filename: 'src/main.vue',
|
||||
content: `<template>
|
||||
<div class="el-${componentname}"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'El${ComponentName}'
|
||||
};
|
||||
</script>`
|
||||
},
|
||||
{
|
||||
filename: path.join('../../examples/docs/zh-CN', `${componentname}.md`),
|
||||
content: `## ${ComponentName} ${chineseName}`
|
||||
},
|
||||
{
|
||||
filename: path.join('../../examples/docs/en-US', `${componentname}.md`),
|
||||
content: `## ${ComponentName}`
|
||||
},
|
||||
{
|
||||
filename: path.join('../../examples/docs/es', `${componentname}.md`),
|
||||
content: `## ${ComponentName}`
|
||||
},
|
||||
{
|
||||
filename: path.join('../../examples/docs/fr-FR', `${componentname}.md`),
|
||||
content: `## ${ComponentName}`
|
||||
},
|
||||
{
|
||||
filename: path.join('../../test/unit/specs', `${componentname}.spec.js`),
|
||||
content: `import { createTest, destroyVM } from '../util';
|
||||
import ${ComponentName} from 'packages/${componentname}';
|
||||
|
||||
describe('${ComponentName}', () => {
|
||||
let vm;
|
||||
afterEach(() => {
|
||||
destroyVM(vm);
|
||||
});
|
||||
|
||||
it('create', () => {
|
||||
vm = createTest(${ComponentName}, true);
|
||||
expect(vm.$el).to.exist;
|
||||
});
|
||||
});
|
||||
`
|
||||
},
|
||||
{
|
||||
filename: path.join('../../packages/theme-chalk/src', `${componentname}.scss`),
|
||||
content: `@import "mixins/mixins";
|
||||
@import "common/var";
|
||||
|
||||
@include b(${componentname}) {
|
||||
}`
|
||||
},
|
||||
{
|
||||
filename: path.join('../../types', `${componentname}.d.ts`),
|
||||
content: `import { ElementUIComponent } from './component'
|
||||
|
||||
/** ${ComponentName} Component */
|
||||
export declare class El${ComponentName} extends ElementUIComponent {
|
||||
}`
|
||||
}
|
||||
];
|
||||
|
||||
// 添加到 components.json
|
||||
const componentsFile = require('../../components.json');
|
||||
if (componentsFile[componentname]) {
|
||||
console.error(`${componentname} 已存在.`);
|
||||
process.exit(1);
|
||||
}
|
||||
componentsFile[componentname] = `./packages/${componentname}/index.js`;
|
||||
fileSave(path.join(__dirname, '../../components.json'))
|
||||
.write(JSON.stringify(componentsFile, null, ' '), 'utf8')
|
||||
.end('\n');
|
||||
|
||||
// 添加到 index.scss
|
||||
const sassPath = path.join(__dirname, '../../packages/theme-chalk/src/index.scss');
|
||||
const sassImportText = `${fs.readFileSync(sassPath)}@import "./${componentname}.scss";`;
|
||||
fileSave(sassPath)
|
||||
.write(sassImportText, 'utf8')
|
||||
.end('\n');
|
||||
|
||||
// 添加到 element-ui.d.ts
|
||||
const elementTsPath = path.join(__dirname, '../../types/element-ui.d.ts');
|
||||
|
||||
let elementTsText = `${fs.readFileSync(elementTsPath)}
|
||||
/** ${ComponentName} Component */
|
||||
export class ${ComponentName} extends El${ComponentName} {}`;
|
||||
|
||||
const index = elementTsText.indexOf('export') - 1;
|
||||
const importString = `import { El${ComponentName} } from './${componentname}'`;
|
||||
|
||||
elementTsText = elementTsText.slice(0, index) + importString + '\n' + elementTsText.slice(index);
|
||||
|
||||
fileSave(elementTsPath)
|
||||
.write(elementTsText, 'utf8')
|
||||
.end('\n');
|
||||
|
||||
// 创建 package
|
||||
Files.forEach(file => {
|
||||
fileSave(path.join(PackagePath, file.filename))
|
||||
.write(file.content, 'utf8')
|
||||
.end('\n');
|
||||
});
|
||||
|
||||
// 添加到 nav.config.json
|
||||
const navConfigFile = require('../../examples/nav.config.json');
|
||||
|
||||
Object.keys(navConfigFile).forEach(lang => {
|
||||
let groups = navConfigFile[lang][4].groups;
|
||||
groups[groups.length - 1].list.push({
|
||||
path: `/${componentname}`,
|
||||
title: lang === 'zh-CN' && componentname !== chineseName
|
||||
? `${ComponentName} ${chineseName}`
|
||||
: ComponentName
|
||||
});
|
||||
});
|
||||
|
||||
fileSave(path.join(__dirname, '../../examples/nav.config.json'))
|
||||
.write(JSON.stringify(navConfigFile, null, ' '), 'utf8')
|
||||
.end('\n');
|
||||
|
||||
console.log('DONE!');
|
16
build/bin/template.js
Normal file
16
build/bin/template.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const path = require('path');
|
||||
const templates = path.resolve(process.cwd(), './examples/pages/template');
|
||||
|
||||
const chokidar = require('chokidar');
|
||||
let watcher = chokidar.watch([templates]);
|
||||
|
||||
watcher.on('ready', function() {
|
||||
watcher
|
||||
.on('change', function() {
|
||||
exec('npm run i18n');
|
||||
});
|
||||
});
|
||||
|
||||
function exec(cmd) {
|
||||
return require('child_process').execSync(cmd).toString().trim();
|
||||
}
|
6
build/bin/version.js
Normal file
6
build/bin/version.js
Normal file
@@ -0,0 +1,6 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var version = process.env.VERSION || require('../../package.json').version;
|
||||
var content = { '1.4.13': '1.4', '2.0.11': '2.0', '2.1.0': '2.1', '2.2.2': '2.2', '2.3.9': '2.3', '2.4.11': '2.4', '2.5.4': '2.5', '2.6.3': '2.6', '2.7.2': '2.7', '2.8.2': '2.8', '2.9.2': '2.9', '2.10.1': '2.10', '2.11.1': '2.11', '2.12.0': '2.12', '2.13.2': '2.13', '2.14.1': '2.14' };
|
||||
if (!content[version]) content[version] = '2.15';
|
||||
fs.writeFileSync(path.resolve(__dirname, '../../examples/versions.json'), JSON.stringify(content));
|
49
build/config.js
Normal file
49
build/config.js
Normal file
@@ -0,0 +1,49 @@
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var nodeExternals = require('webpack-node-externals');
|
||||
var Components = require('../components.json');
|
||||
|
||||
var utilsList = fs.readdirSync(path.resolve(__dirname, '../src/utils'));
|
||||
var mixinsList = fs.readdirSync(path.resolve(__dirname, '../src/mixins'));
|
||||
var transitionList = fs.readdirSync(path.resolve(__dirname, '../src/transitions'));
|
||||
var externals = {};
|
||||
|
||||
Object.keys(Components).forEach(function(key) {
|
||||
externals[`element-ui/packages/${key}`] = `element-ui/lib/${key}`;
|
||||
});
|
||||
|
||||
externals['element-ui/src/locale'] = 'element-ui/lib/locale';
|
||||
utilsList.forEach(function(file) {
|
||||
file = path.basename(file, '.js');
|
||||
externals[`element-ui/src/utils/${file}`] = `element-ui/lib/utils/${file}`;
|
||||
});
|
||||
mixinsList.forEach(function(file) {
|
||||
file = path.basename(file, '.js');
|
||||
externals[`element-ui/src/mixins/${file}`] = `element-ui/lib/mixins/${file}`;
|
||||
});
|
||||
transitionList.forEach(function(file) {
|
||||
file = path.basename(file, '.js');
|
||||
externals[`element-ui/src/transitions/${file}`] = `element-ui/lib/transitions/${file}`;
|
||||
});
|
||||
|
||||
externals = [Object.assign({
|
||||
vue: 'vue'
|
||||
}, externals), nodeExternals()];
|
||||
|
||||
exports.externals = externals;
|
||||
|
||||
exports.alias = {
|
||||
main: path.resolve(__dirname, '../src'),
|
||||
packages: path.resolve(__dirname, '../packages'),
|
||||
examples: path.resolve(__dirname, '../examples'),
|
||||
'element-ui': path.resolve(__dirname, '../')
|
||||
};
|
||||
|
||||
exports.vue = {
|
||||
root: 'Vue',
|
||||
commonjs: 'vue',
|
||||
commonjs2: 'vue',
|
||||
amd: 'vue'
|
||||
};
|
||||
|
||||
exports.jsexclude = /node_modules|utils\/popper\.js|utils\/date\.js/;
|
78
build/deploy-ci.sh
Normal file
78
build/deploy-ci.sh
Normal file
@@ -0,0 +1,78 @@
|
||||
#! /bin/sh
|
||||
mkdir temp_web
|
||||
git config --global user.name "element-bot"
|
||||
git config --global user.email "wallement@gmail.com"
|
||||
|
||||
if [ "$ROT_TOKEN" = "" ]; then
|
||||
echo "Bye~"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# release
|
||||
if [ "$TRAVIS_TAG" ]; then
|
||||
# build lib
|
||||
npm run dist
|
||||
cd temp_web
|
||||
git clone https://$ROT_TOKEN@github.com/ElementUI/lib.git && cd lib
|
||||
rm -rf `find * ! -name README.md`
|
||||
cp -rf ../../lib/** .
|
||||
git add -A .
|
||||
git commit -m "[build] $TRAVIS_TAG"
|
||||
git tag $TRAVIS_TAG
|
||||
git push origin master --tags
|
||||
cd ../..
|
||||
|
||||
# build theme-chalk
|
||||
cd temp_web
|
||||
git clone https://$ROT_TOKEN@github.com/ElementUI/theme-chalk.git && cd theme-chalk
|
||||
rm -rf *
|
||||
cp -rf ../../packages/theme-chalk/** .
|
||||
git add -A .
|
||||
git commit -m "[build] $TRAVIS_TAG"
|
||||
git tag $TRAVIS_TAG
|
||||
git push origin master --tags
|
||||
cd ../..
|
||||
|
||||
# build site
|
||||
npm run deploy:build
|
||||
cd temp_web
|
||||
git clone --depth 1 -b gh-pages --single-branch https://$ROT_TOKEN@github.com/ElemeFE/element.git && cd element
|
||||
# build sub folder
|
||||
echo $TRAVIS_TAG
|
||||
|
||||
SUB_FOLDER='2.15'
|
||||
mkdir $SUB_FOLDER
|
||||
rm -rf *.js *.css *.map static
|
||||
rm -rf $SUB_FOLDER/**
|
||||
cp -rf ../../examples/element-ui/** .
|
||||
cp -rf ../../examples/element-ui/** $SUB_FOLDER/
|
||||
git add -A .
|
||||
git commit -m "$TRAVIS_COMMIT_MSG"
|
||||
git push origin gh-pages
|
||||
cd ../..
|
||||
|
||||
echo "DONE, Bye~"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# build dev site
|
||||
npm run build:file && CI_ENV=/dev/$TRAVIS_BRANCH/ node_modules/.bin/cross-env NODE_ENV=production node_modules/.bin/webpack --config build/webpack.demo.js
|
||||
cd temp_web
|
||||
git clone https://$ROT_TOKEN@github.com/ElementUI/dev.git && cd dev
|
||||
mkdir $TRAVIS_BRANCH
|
||||
rm -rf $TRAVIS_BRANCH/**
|
||||
cp -rf ../../examples/element-ui/** $TRAVIS_BRANCH/
|
||||
git add -A .
|
||||
git commit -m "$TRAVIS_COMMIT_MSG"
|
||||
git push origin master
|
||||
cd ../..
|
||||
|
||||
# push dev theme-chalk
|
||||
cd temp_web
|
||||
git clone -b $TRAVIS_BRANCH https://$ROT_TOKEN@github.com/ElementUI/theme-chalk.git && cd theme-chalk
|
||||
rm -rf *
|
||||
cp -rf ../../packages/theme-chalk/** .
|
||||
git add -A .
|
||||
git commit -m "$TRAVIS_COMMIT_MSG"
|
||||
git push origin $TRAVIS_BRANCH
|
||||
cd ../..
|
19
build/deploy-faas.sh
Normal file
19
build/deploy-faas.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#! /bin/sh
|
||||
set -ex
|
||||
mkdir temp_web
|
||||
npm run deploy:build
|
||||
cd temp_web
|
||||
git clone --depth 1 -b gh-pages --single-branch https://github.com/ElemeFE/element.git && cd element
|
||||
|
||||
# build sub folder
|
||||
SUB_FOLDER='2.15'
|
||||
mkdir -p $SUB_FOLDER
|
||||
rm -rf *.js *.css *.map static
|
||||
rm -rf $SUB_FOLDER/**
|
||||
cp -rf ../../examples/element-ui/** .
|
||||
cp -rf ../../examples/element-ui/** $SUB_FOLDER/
|
||||
cd ../..
|
||||
|
||||
# deploy domestic site
|
||||
faas deploy daily -P element
|
||||
rm -rf temp_web
|
17
build/gen-single-config.js
Normal file
17
build/gen-single-config.js
Normal file
@@ -0,0 +1,17 @@
|
||||
var path = require('path');
|
||||
var config = require('./config');
|
||||
|
||||
module.exports = function(context, moduleName, entry) {
|
||||
return {
|
||||
entry: {
|
||||
index: path.resolve(context, entry || 'index.js')
|
||||
},
|
||||
dist: path.resolve(context, 'lib'),
|
||||
template: false,
|
||||
format: 'umd',
|
||||
moduleName: moduleName,
|
||||
extends: ['vue2'],
|
||||
alias: config.alias,
|
||||
externals: { vue: config.vue }
|
||||
};
|
||||
};
|
19
build/git-release.sh
Normal file
19
build/git-release.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env sh
|
||||
git checkout dev
|
||||
|
||||
if test -n "$(git status --porcelain)"; then
|
||||
echo 'Unclean working tree. Commit or stash changes first.' >&2;
|
||||
exit 128;
|
||||
fi
|
||||
|
||||
if ! git fetch --quiet 2>/dev/null; then
|
||||
echo 'There was a problem fetching your branch. Run `git fetch` to see more...' >&2;
|
||||
exit 128;
|
||||
fi
|
||||
|
||||
if test "0" != "$(git rev-list --count --left-only @'{u}'...HEAD)"; then
|
||||
echo 'Remote history differ. Please pull changes.' >&2;
|
||||
exit 128;
|
||||
fi
|
||||
|
||||
echo 'No conflicts.' >&2;
|
26
build/md-loader/config.js
Normal file
26
build/md-loader/config.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const Config = require('markdown-it-chain');
|
||||
const anchorPlugin = require('markdown-it-anchor');
|
||||
const slugify = require('transliteration').slugify;
|
||||
const containers = require('./containers');
|
||||
const overWriteFenceRule = require('./fence');
|
||||
|
||||
const config = new Config();
|
||||
|
||||
config
|
||||
.options.html(true).end()
|
||||
|
||||
.plugin('anchor').use(anchorPlugin, [
|
||||
{
|
||||
level: 2,
|
||||
slugify: slugify,
|
||||
permalink: true,
|
||||
permalinkBefore: true
|
||||
}
|
||||
]).end()
|
||||
|
||||
.plugin('containers').use(containers).end();
|
||||
|
||||
const md = config.toMd();
|
||||
overWriteFenceRule(md);
|
||||
|
||||
module.exports = md;
|
24
build/md-loader/containers.js
Normal file
24
build/md-loader/containers.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const mdContainer = require('markdown-it-container');
|
||||
|
||||
module.exports = md => {
|
||||
md.use(mdContainer, 'demo', {
|
||||
validate(params) {
|
||||
return params.trim().match(/^demo\s*(.*)$/);
|
||||
},
|
||||
render(tokens, idx) {
|
||||
const m = tokens[idx].info.trim().match(/^demo\s*(.*)$/);
|
||||
if (tokens[idx].nesting === 1) {
|
||||
const description = m && m.length > 1 ? m[1] : '';
|
||||
const content = tokens[idx + 1].type === 'fence' ? tokens[idx + 1].content : '';
|
||||
return `<demo-block>
|
||||
${description ? `<div>${md.render(description)}</div>` : ''}
|
||||
<!--element-demo: ${content}:element-demo-->
|
||||
`;
|
||||
}
|
||||
return '</demo-block>';
|
||||
}
|
||||
});
|
||||
|
||||
md.use(mdContainer, 'tip');
|
||||
md.use(mdContainer, 'warning');
|
||||
};
|
14
build/md-loader/fence.js
Normal file
14
build/md-loader/fence.js
Normal file
@@ -0,0 +1,14 @@
|
||||
// 覆盖默认的 fence 渲染策略
|
||||
module.exports = md => {
|
||||
const defaultRender = md.renderer.rules.fence;
|
||||
md.renderer.rules.fence = (tokens, idx, options, env, self) => {
|
||||
const token = tokens[idx];
|
||||
// 判断该 fence 是否在 :::demo 内
|
||||
const prevToken = tokens[idx - 1];
|
||||
const isInDemoContainer = prevToken && prevToken.nesting === 1 && prevToken.info.trim().match(/^demo\s*(.*)$/);
|
||||
if (token.info === 'html' && isInDemoContainer) {
|
||||
return `<template slot="highlight"><pre v-pre><code class="html">${md.utils.escapeHtml(token.content)}</code></pre></template>`;
|
||||
}
|
||||
return defaultRender(tokens, idx, options, env, self);
|
||||
};
|
||||
};
|
67
build/md-loader/index.js
Normal file
67
build/md-loader/index.js
Normal file
@@ -0,0 +1,67 @@
|
||||
const {
|
||||
stripScript,
|
||||
stripTemplate,
|
||||
genInlineComponentText
|
||||
} = require('./util');
|
||||
const md = require('./config');
|
||||
|
||||
module.exports = function(source) {
|
||||
const content = md.render(source);
|
||||
|
||||
const startTag = '<!--element-demo:';
|
||||
const startTagLen = startTag.length;
|
||||
const endTag = ':element-demo-->';
|
||||
const endTagLen = endTag.length;
|
||||
|
||||
let componenetsString = '';
|
||||
let id = 0; // demo 的 id
|
||||
let output = []; // 输出的内容
|
||||
let start = 0; // 字符串开始位置
|
||||
|
||||
let commentStart = content.indexOf(startTag);
|
||||
let commentEnd = content.indexOf(endTag, commentStart + startTagLen);
|
||||
while (commentStart !== -1 && commentEnd !== -1) {
|
||||
output.push(content.slice(start, commentStart));
|
||||
|
||||
const commentContent = content.slice(commentStart + startTagLen, commentEnd);
|
||||
const html = stripTemplate(commentContent);
|
||||
const script = stripScript(commentContent);
|
||||
let demoComponentContent = genInlineComponentText(html, script);
|
||||
const demoComponentName = `element-demo${id}`;
|
||||
output.push(`<template slot="source"><${demoComponentName} /></template>`);
|
||||
componenetsString += `${JSON.stringify(demoComponentName)}: ${demoComponentContent},`;
|
||||
|
||||
// 重新计算下一次的位置
|
||||
id++;
|
||||
start = commentEnd + endTagLen;
|
||||
commentStart = content.indexOf(startTag, start);
|
||||
commentEnd = content.indexOf(endTag, commentStart + startTagLen);
|
||||
}
|
||||
|
||||
// 仅允许在 demo 不存在时,才可以在 Markdown 中写 script 标签
|
||||
// todo: 优化这段逻辑
|
||||
let pageScript = '';
|
||||
if (componenetsString) {
|
||||
pageScript = `<script>
|
||||
export default {
|
||||
name: 'component-doc',
|
||||
components: {
|
||||
${componenetsString}
|
||||
}
|
||||
}
|
||||
</script>`;
|
||||
} else if (content.indexOf('<script>') === 0) { // 硬编码,有待改善
|
||||
start = content.indexOf('</script>') + '</script>'.length;
|
||||
pageScript = content.slice(0, start);
|
||||
}
|
||||
|
||||
output.push(content.slice(start));
|
||||
return `
|
||||
<template>
|
||||
<section class="content element-doc">
|
||||
${output.join('')}
|
||||
</section>
|
||||
</template>
|
||||
${pageScript}
|
||||
`;
|
||||
};
|
79
build/md-loader/util.js
Normal file
79
build/md-loader/util.js
Normal file
@@ -0,0 +1,79 @@
|
||||
const { compileTemplate } = require('@vue/component-compiler-utils');
|
||||
const compiler = require('vue-template-compiler');
|
||||
|
||||
function stripScript(content) {
|
||||
const result = content.match(/<(script)>([\s\S]+)<\/\1>/);
|
||||
return result && result[2] ? result[2].trim() : '';
|
||||
}
|
||||
|
||||
function stripStyle(content) {
|
||||
const result = content.match(/<(style)\s*>([\s\S]+)<\/\1>/);
|
||||
return result && result[2] ? result[2].trim() : '';
|
||||
}
|
||||
|
||||
// 编写例子时不一定有 template。所以采取的方案是剔除其他的内容
|
||||
function stripTemplate(content) {
|
||||
content = content.trim();
|
||||
if (!content) {
|
||||
return content;
|
||||
}
|
||||
return content.replace(/<(script|style)[\s\S]+<\/\1>/g, '').trim();
|
||||
}
|
||||
|
||||
function pad(source) {
|
||||
return source
|
||||
.split(/\r?\n/)
|
||||
.map(line => ` ${line}`)
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
function genInlineComponentText(template, script) {
|
||||
// https://github.com/vuejs/vue-loader/blob/423b8341ab368c2117931e909e2da9af74503635/lib/loaders/templateLoader.js#L46
|
||||
const finalOptions = {
|
||||
source: `<div>${template}</div>`,
|
||||
filename: 'inline-component', // TODO:这里有待调整
|
||||
compiler
|
||||
};
|
||||
const compiled = compileTemplate(finalOptions);
|
||||
// tips
|
||||
if (compiled.tips && compiled.tips.length) {
|
||||
compiled.tips.forEach(tip => {
|
||||
console.warn(tip);
|
||||
});
|
||||
}
|
||||
// errors
|
||||
if (compiled.errors && compiled.errors.length) {
|
||||
console.error(
|
||||
`\n Error compiling template:\n${pad(compiled.source)}\n` +
|
||||
compiled.errors.map(e => ` - ${e}`).join('\n') +
|
||||
'\n'
|
||||
);
|
||||
}
|
||||
let demoComponentContent = `
|
||||
${compiled.code}
|
||||
`;
|
||||
// todo: 这里采用了硬编码有待改进
|
||||
script = script.trim();
|
||||
if (script) {
|
||||
script = script.replace(/export\s+default/, 'const democomponentExport =');
|
||||
} else {
|
||||
script = 'const democomponentExport = {}';
|
||||
}
|
||||
demoComponentContent = `(function() {
|
||||
${demoComponentContent}
|
||||
${script}
|
||||
return {
|
||||
render,
|
||||
staticRenderFns,
|
||||
...democomponentExport
|
||||
}
|
||||
})()`;
|
||||
return demoComponentContent;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
stripScript,
|
||||
stripStyle,
|
||||
stripTemplate,
|
||||
genInlineComponentText
|
||||
};
|
51
build/release.sh
Normal file
51
build/release.sh
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
git checkout master
|
||||
git merge dev
|
||||
|
||||
VERSION=`npx select-version-cli`
|
||||
|
||||
read -p "Releasing $VERSION - are you sure? (y/n)" -n 1 -r
|
||||
echo # (optional) move to a new line
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]
|
||||
then
|
||||
echo "Releasing $VERSION ..."
|
||||
|
||||
# build
|
||||
VERSION=$VERSION npm run dist
|
||||
|
||||
# ssr test
|
||||
node test/ssr/require.test.js
|
||||
|
||||
# publish theme
|
||||
echo "Releasing theme-chalk $VERSION ..."
|
||||
cd packages/theme-chalk
|
||||
npm version $VERSION --message "[release] $VERSION"
|
||||
if [[ $VERSION =~ "beta" ]]
|
||||
then
|
||||
npm publish --tag beta
|
||||
else
|
||||
npm publish
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
# commit
|
||||
git add -A
|
||||
git commit -m "[build] $VERSION"
|
||||
npm version $VERSION --message "[release] $VERSION"
|
||||
|
||||
# publish
|
||||
git push eleme master
|
||||
git push eleme refs/tags/v$VERSION
|
||||
git checkout dev
|
||||
git rebase master
|
||||
git push eleme dev
|
||||
|
||||
if [[ $VERSION =~ "beta" ]]
|
||||
then
|
||||
npm publish --tag beta
|
||||
else
|
||||
npm publish
|
||||
fi
|
||||
fi
|
71
build/webpack.common.js
Normal file
71
build/webpack.common.js
Normal file
@@ -0,0 +1,71 @@
|
||||
const path = require('path');
|
||||
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||
|
||||
const config = require('./config');
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: {
|
||||
app: ['./src/index.js']
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(process.cwd(), './lib'),
|
||||
publicPath: '/dist/',
|
||||
filename: 'element-ui.common.js',
|
||||
chunkFilename: '[id].js',
|
||||
libraryExport: 'default',
|
||||
library: 'ELEMENT',
|
||||
libraryTarget: 'commonjs2'
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: config.alias,
|
||||
modules: ['node_modules']
|
||||
},
|
||||
externals: config.externals,
|
||||
performance: {
|
||||
hints: false
|
||||
},
|
||||
stats: {
|
||||
children: false
|
||||
},
|
||||
optimization: {
|
||||
minimize: false
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(jsx?|babel|es6)$/,
|
||||
include: process.cwd(),
|
||||
exclude: config.jsexclude,
|
||||
loader: 'babel-loader'
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
compilerOptions: {
|
||||
preserveWhitespace: false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
loaders: ['style-loader', 'css-loader']
|
||||
},
|
||||
{
|
||||
test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/,
|
||||
loader: 'url-loader',
|
||||
query: {
|
||||
limit: 10000,
|
||||
name: path.posix.join('static', '[name].[hash:7].[ext]')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new ProgressBarPlugin(),
|
||||
new VueLoaderPlugin()
|
||||
]
|
||||
};
|
68
build/webpack.component.js
Normal file
68
build/webpack.component.js
Normal file
@@ -0,0 +1,68 @@
|
||||
const path = require('path');
|
||||
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||
|
||||
const Components = require('../components.json');
|
||||
const config = require('./config');
|
||||
|
||||
const webpackConfig = {
|
||||
mode: 'production',
|
||||
entry: Components,
|
||||
output: {
|
||||
path: path.resolve(process.cwd(), './lib'),
|
||||
publicPath: '/dist/',
|
||||
filename: '[name].js',
|
||||
chunkFilename: '[id].js',
|
||||
libraryTarget: 'commonjs2'
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: config.alias,
|
||||
modules: ['node_modules']
|
||||
},
|
||||
externals: config.externals,
|
||||
performance: {
|
||||
hints: false
|
||||
},
|
||||
stats: 'none',
|
||||
optimization: {
|
||||
minimize: false
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(jsx?|babel|es6)$/,
|
||||
include: process.cwd(),
|
||||
exclude: config.jsexclude,
|
||||
loader: 'babel-loader'
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
compilerOptions: {
|
||||
preserveWhitespace: false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
loaders: ['style-loader', 'css-loader']
|
||||
},
|
||||
{
|
||||
test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/,
|
||||
loader: 'url-loader',
|
||||
query: {
|
||||
limit: 10000,
|
||||
name: path.posix.join('static', '[name].[hash:7].[ext]')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new ProgressBarPlugin(),
|
||||
new VueLoaderPlugin()
|
||||
]
|
||||
};
|
||||
|
||||
module.exports = webpackConfig;
|
71
build/webpack.conf.js
Normal file
71
build/webpack.conf.js
Normal file
@@ -0,0 +1,71 @@
|
||||
const path = require('path');
|
||||
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
|
||||
const config = require('./config');
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: {
|
||||
app: ['./src/index.js']
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(process.cwd(), './lib'),
|
||||
publicPath: '/dist/',
|
||||
filename: 'index.js',
|
||||
chunkFilename: '[id].js',
|
||||
libraryTarget: 'umd',
|
||||
libraryExport: 'default',
|
||||
library: 'ELEMENT',
|
||||
umdNamedDefine: true,
|
||||
globalObject: 'typeof self !== \'undefined\' ? self : this'
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: config.alias
|
||||
},
|
||||
externals: {
|
||||
vue: config.vue
|
||||
},
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
terserOptions: {
|
||||
output: {
|
||||
comments: false
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
},
|
||||
performance: {
|
||||
hints: false
|
||||
},
|
||||
stats: {
|
||||
children: false
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(jsx?|babel|es6)$/,
|
||||
include: process.cwd(),
|
||||
exclude: config.jsexclude,
|
||||
loader: 'babel-loader'
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
compilerOptions: {
|
||||
preserveWhitespace: false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new ProgressBarPlugin(),
|
||||
new VueLoaderPlugin()
|
||||
]
|
||||
};
|
163
build/webpack.demo.js
Normal file
163
build/webpack.demo.js
Normal file
@@ -0,0 +1,163 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||
|
||||
const config = require('./config');
|
||||
|
||||
const isProd = process.env.NODE_ENV === 'production';
|
||||
const isPlay = !!process.env.PLAY_ENV;
|
||||
|
||||
const webpackConfig = {
|
||||
mode: process.env.NODE_ENV,
|
||||
entry: isProd ? {
|
||||
docs: './examples/entry.js'
|
||||
} : (isPlay ? './examples/play.js' : './examples/entry.js'),
|
||||
output: {
|
||||
path: path.resolve(process.cwd(), './examples/element-ui/'),
|
||||
publicPath: process.env.CI_ENV || '',
|
||||
filename: '[name].[hash:7].js',
|
||||
chunkFilename: isProd ? '[name].[hash:7].js' : '[name].js'
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: config.alias,
|
||||
modules: ['node_modules']
|
||||
},
|
||||
devServer: {
|
||||
host: '0.0.0.0',
|
||||
port: 8085,
|
||||
publicPath: '/',
|
||||
hot: true
|
||||
},
|
||||
performance: {
|
||||
hints: false
|
||||
},
|
||||
stats: {
|
||||
children: false
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
enforce: 'pre',
|
||||
test: /\.(vue|jsx?)$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'eslint-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(jsx?|babel|es6)$/,
|
||||
include: process.cwd(),
|
||||
exclude: config.jsexclude,
|
||||
loader: 'babel-loader'
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
compilerOptions: {
|
||||
preserveWhitespace: false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(scss|css)$/,
|
||||
use: [
|
||||
isProd ? MiniCssExtractPlugin.loader : 'style-loader',
|
||||
'css-loader',
|
||||
'sass-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.md$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
compilerOptions: {
|
||||
preserveWhitespace: false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
loader: path.resolve(__dirname, './md-loader/index.js')
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/,
|
||||
loader: 'url-loader',
|
||||
// todo: 这种写法有待调整
|
||||
query: {
|
||||
limit: 10000,
|
||||
name: path.posix.join('static', '[name].[hash:7].[ext]')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new HtmlWebpackPlugin({
|
||||
template: './examples/index.tpl',
|
||||
filename: './index.html',
|
||||
favicon: './examples/favicon.ico'
|
||||
}),
|
||||
new CopyWebpackPlugin([
|
||||
{ from: 'examples/versions.json' }
|
||||
]),
|
||||
new ProgressBarPlugin(),
|
||||
new VueLoaderPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.FAAS_ENV': JSON.stringify(process.env.FAAS_ENV)
|
||||
}),
|
||||
new webpack.LoaderOptionsPlugin({
|
||||
vue: {
|
||||
compilerOptions: {
|
||||
preserveWhitespace: false
|
||||
}
|
||||
}
|
||||
})
|
||||
],
|
||||
optimization: {
|
||||
minimizer: []
|
||||
},
|
||||
devtool: '#eval-source-map'
|
||||
};
|
||||
|
||||
if (isProd) {
|
||||
webpackConfig.externals = {
|
||||
vue: 'Vue',
|
||||
'vue-router': 'VueRouter',
|
||||
'highlight.js': 'hljs'
|
||||
};
|
||||
webpackConfig.plugins.push(
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name].[contenthash:7].css'
|
||||
})
|
||||
);
|
||||
webpackConfig.optimization.minimizer.push(
|
||||
new UglifyJsPlugin({
|
||||
cache: true,
|
||||
parallel: true,
|
||||
sourceMap: false
|
||||
}),
|
||||
new OptimizeCSSAssetsPlugin({})
|
||||
);
|
||||
// https://webpack.js.org/configuration/optimization/#optimizationsplitchunks
|
||||
webpackConfig.optimization.splitChunks = {
|
||||
cacheGroups: {
|
||||
vendor: {
|
||||
test: /\/src\//,
|
||||
name: 'element-ui',
|
||||
chunks: 'all'
|
||||
}
|
||||
}
|
||||
};
|
||||
webpackConfig.devtool = false;
|
||||
}
|
||||
|
||||
module.exports = webpackConfig;
|
33
build/webpack.extension.js
Normal file
33
build/webpack.extension.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const path = require('path');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const demoConfig = require('./webpack.demo');
|
||||
const webpack = require('webpack');
|
||||
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||
|
||||
demoConfig.entry = {
|
||||
background: path.join(process.cwd(), './examples/extension/src/background'),
|
||||
entry: path.join(process.cwd(), './examples/extension/src/entry')
|
||||
};
|
||||
demoConfig.output = {
|
||||
path: path.join(process.cwd(), './examples/extension/dist'),
|
||||
filename: '[name].js'
|
||||
};
|
||||
demoConfig.plugins = [
|
||||
new CopyWebpackPlugin([
|
||||
{ from: 'examples/extension/src/manifest.json' },
|
||||
{ from: 'examples/extension/src/icon.png' }
|
||||
]),
|
||||
new VueLoaderPlugin(),
|
||||
new ProgressBarPlugin(),
|
||||
new webpack.LoaderOptionsPlugin({
|
||||
vue: {
|
||||
compilerOptions: {
|
||||
preserveWhitespace: false
|
||||
}
|
||||
}
|
||||
}),
|
||||
new webpack.HotModuleReplacementPlugin()
|
||||
];
|
||||
demoConfig.module.rules.find(a => a.loader === 'url-loader').query = {};
|
||||
module.exports = demoConfig;
|
67
build/webpack.test.js
Normal file
67
build/webpack.test.js
Normal file
@@ -0,0 +1,67 @@
|
||||
const path = require('path');
|
||||
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||
|
||||
const config = require('./config');
|
||||
|
||||
const webpackConfig = {
|
||||
mode: 'development',
|
||||
entry: {
|
||||
app: ['./src/index.js']
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(process.cwd(), './dist'),
|
||||
publicPath: '/dist/',
|
||||
filename: '[name].js',
|
||||
chunkFilename: '[id].js'
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: Object.assign(config.alias, {
|
||||
'vue$': 'vue/dist/vue.common.js'
|
||||
}),
|
||||
modules: ['node_modules']
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(jsx?|babel|es6)$/,
|
||||
include: process.cwd(),
|
||||
exclude: config.jsexclude,
|
||||
loader: 'babel-loader'
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
compilerOptions: {
|
||||
preserveWhitespace: false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
loaders: ['style-loader', 'css-loader']
|
||||
},
|
||||
{
|
||||
test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/,
|
||||
loader: 'url-loader',
|
||||
query: {
|
||||
limit: 10000,
|
||||
name: path.posix.join('static', '[name].[hash:7].[ext]')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new VueLoaderPlugin()
|
||||
]
|
||||
};
|
||||
|
||||
if (!process.env.CI_ENV) {
|
||||
webpackConfig.plugins.push(
|
||||
new ProgressBarPlugin()
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = webpackConfig;
|
Reference in New Issue
Block a user