webpack.demo.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. const path = require('path');
  2. const webpack = require('webpack');
  3. const CopyWebpackPlugin = require('copy-webpack-plugin');
  4. const HtmlWebpackPlugin = require('html-webpack-plugin');
  5. const ExtractTextPlugin = require('extract-text-webpack-plugin');
  6. const ProgressBarPlugin = require('progress-bar-webpack-plugin');
  7. const md = require('markdown-it')();
  8. const slugify = require('transliteration').slugify;
  9. const striptags = require('./strip-tags');
  10. const config = require('./config');
  11. const isProd = process.env.NODE_ENV === 'production';
  12. const isDev = process.env.NODE_ENV === 'development';
  13. const isPlay = !!process.env.PLAY_ENV;
  14. function convert(str) {
  15. str = str.replace(/(&#x)(\w{4});/gi, function($0) {
  16. return String.fromCharCode(parseInt(encodeURIComponent($0).replace(/(%26%23x)(\w{4})(%3B)/g, '$2'), 16));
  17. });
  18. return str;
  19. }
  20. function wrap(render) {
  21. return function() {
  22. return render.apply(this, arguments)
  23. .replace('<code v-pre class="', '<code class="hljs ')
  24. .replace('<code>', '<code class="hljs">');
  25. };
  26. }
  27. const webpackConfig = {
  28. entry: isProd ? {
  29. docs: './examples/entry.js',
  30. 'element-ui': './src/index.js'
  31. } : (isPlay ? './examples/play.js' : './examples/entry.js'),
  32. output: {
  33. path: path.resolve(process.cwd(), './examples/element-ui/'),
  34. publicPath: process.env.CI_ENV || '',
  35. filename: '[name].[hash:7].js',
  36. chunkFilename: isProd ? '[name].[hash:7].js' : '[name].js'
  37. },
  38. resolve: {
  39. extensions: ['.js', '.vue', '.json'],
  40. alias: config.alias,
  41. modules: ['node_modules']
  42. },
  43. devServer: {
  44. host: '0.0.0.0',
  45. port: 8085,
  46. publicPath: '/',
  47. noInfo: true
  48. },
  49. module: {
  50. rules: [
  51. {
  52. enforce: 'pre',
  53. test: /\.jsx?$/,
  54. exclude: /node_modules|bower_components/,
  55. loader: 'eslint-loader'
  56. },
  57. {
  58. enforce: 'pre',
  59. test: /\.vue$/,
  60. exclude: /node_modules|bower_components/,
  61. loader: 'eslint-loader'
  62. },
  63. {
  64. test: /\.(jsx?|babel|es6)$/,
  65. include: process.cwd(),
  66. exclude: config.jsexclude,
  67. loader: 'babel-loader'
  68. },
  69. {
  70. test: /\.md$/,
  71. loader: 'vue-markdown-loader',
  72. options: {
  73. use: [
  74. [require('markdown-it-anchor'), {
  75. level: 2,
  76. slugify: slugify,
  77. permalink: true,
  78. permalinkBefore: true
  79. }],
  80. [require('markdown-it-container'), 'demo', {
  81. validate: function(params) {
  82. return params.trim().match(/^demo\s*(.*)$/);
  83. },
  84. render: function(tokens, idx) {
  85. var m = tokens[idx].info.trim().match(/^demo\s*(.*)$/);
  86. if (tokens[idx].nesting === 1) {
  87. var description = (m && m.length > 1) ? m[1] : '';
  88. var content = tokens[idx + 1].content;
  89. var html = convert(striptags.strip(content, ['script', 'style'])).replace(/(<[^>]*)=""(?=.*>)/g, '$1');
  90. var script = striptags.fetch(content, 'script');
  91. var style = striptags.fetch(content, 'style');
  92. var jsfiddle = { html: html, script: script, style: style };
  93. var descriptionHTML = description
  94. ? md.render(description)
  95. : '';
  96. jsfiddle = md.utils.escapeHtml(JSON.stringify(jsfiddle));
  97. return `<demo-block class="demo-box" :jsfiddle="${jsfiddle}">
  98. <div class="source" slot="source">${html}</div>
  99. ${descriptionHTML}
  100. <div class="highlight" slot="highlight">`;
  101. }
  102. return '</div></demo-block>\n';
  103. }
  104. }],
  105. [require('markdown-it-container'), 'tip'],
  106. [require('markdown-it-container'), 'warning']
  107. ],
  108. preprocess: function(MarkdownIt, source) {
  109. MarkdownIt.renderer.rules.table_open = function() {
  110. return '<table class="table">';
  111. };
  112. MarkdownIt.renderer.rules.fence = wrap(MarkdownIt.renderer.rules.fence);
  113. return source;
  114. }
  115. }
  116. },
  117. {
  118. test: /\.json$/,
  119. loader: 'json-loader'
  120. },
  121. {
  122. test: /\.scss$/,
  123. loaders: ['style-loader', 'css-loader', 'sass-loader']
  124. },
  125. {
  126. test: /\.html$/,
  127. loader: 'html-loader?minimize=false'
  128. },
  129. {
  130. test: /\.otf|ttf|woff2?|eot(\?\S*)?$/,
  131. loader: 'url-loader',
  132. query: {
  133. limit: 10000,
  134. name: path.posix.join('static', '[name].[hash:7].[ext]')
  135. }
  136. },
  137. {
  138. test: /\.svg(\?\S*)?$/,
  139. loader: 'url-loader',
  140. query: {
  141. limit: 10000,
  142. name: path.posix.join('static', '[name].[hash:7].[ext]')
  143. }
  144. },
  145. {
  146. test: /\.(gif|png|jpe?g)(\?\S*)?$/,
  147. loader: 'url-loader',
  148. query: {
  149. limit: 10000,
  150. name: path.posix.join('static', '[name].[hash:7].[ext]')
  151. }
  152. }
  153. ]
  154. },
  155. plugins: [
  156. new HtmlWebpackPlugin({
  157. template: './examples/index.tpl',
  158. filename: './index.html',
  159. favicon: './examples/favicon.ico'
  160. }),
  161. new CopyWebpackPlugin([
  162. { from: 'examples/versions.json' }
  163. ]),
  164. new ProgressBarPlugin(),
  165. new webpack.LoaderOptionsPlugin({
  166. minimize: true,
  167. vue: {
  168. preserveWhitespace: false
  169. }
  170. })
  171. ]
  172. };
  173. if (isProd) {
  174. webpackConfig.externals = {
  175. vue: 'Vue',
  176. 'vue-router': 'VueRouter'
  177. };
  178. webpackConfig.module.rules.push(
  179. {
  180. test: /\.vue$/,
  181. loader: 'vue-loader',
  182. options: {
  183. extractCSS: true,
  184. preserveWhitespace: false
  185. }
  186. },
  187. {
  188. test: /\.css$/,
  189. loader: ExtractTextPlugin.extract({
  190. fallback: 'style-loader',
  191. use: [
  192. { loader: 'css-loader', options: { importLoaders: 1 } },
  193. 'postcss-loader'
  194. ]
  195. })
  196. }
  197. );
  198. webpackConfig.plugins.push(
  199. new webpack.optimize.UglifyJsPlugin({
  200. compress: {
  201. warnings: false
  202. },
  203. output: {
  204. comments: false
  205. },
  206. sourceMap: false
  207. }),
  208. new ExtractTextPlugin({
  209. filename: '[name].[contenthash:7].css'
  210. }),
  211. new webpack.DefinePlugin({
  212. 'process.env.NODE_ENV': JSON.stringify('production')
  213. }),
  214. new webpack.optimize.CommonsChunkPlugin({
  215. name: ['element-ui', 'manifest']
  216. })
  217. );
  218. }
  219. if (isDev) {
  220. webpackConfig.module.rules.push(
  221. {
  222. test: /\.vue$/,
  223. loader: 'vue-loader',
  224. options: {
  225. preserveWhitespace: false
  226. }
  227. },
  228. {
  229. test: /\.css$/,
  230. loaders: ['style-loader', 'css-loader', 'postcss-loader']
  231. }
  232. );
  233. webpackConfig.plugins.push(
  234. new webpack.HotModuleReplacementPlugin(),
  235. new webpack.NamedModulesPlugin(),
  236. new webpack.DefinePlugin({
  237. 'process.env.NODE_ENV': JSON.stringify('development')
  238. })
  239. );
  240. }
  241. module.exports = webpackConfig;