const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const MarkdownItContainer = require('markdown-it-container'); const MarkdownItCheckBox = require('markdown-it-task-checkbox'); const MarkdownItDec = require('markdown-it-decorate'); /** * 增加 hljs 的 classname */ const wrapCustomClass = function (render) { return function (...args) { return render(...args) .replace('', ''); }; }; const vueMarkdown = { raw: true, // 定义处理规则 preprocess: function (MarkdownIt, source) { // 表格 MarkdownIt.renderer.rules.table_open = function () { return ''; }; // ```html``` 给这种样式加个class hljs MarkdownIt.renderer.rules.fence = wrapCustomClass( MarkdownIt.renderer.rules.fence ); // ```code``` 给这种样式加个class code_inline const codeInline = MarkdownIt.renderer.rules.code_inline; MarkdownIt.renderer.rules.code_inline = function (...args) { args[0][args[1]].attrJoin('class', 'code_inline'); return codeInline(...args); }; return source; }, use: [ // 'markdown-it-container'的作用是自定义代码块 [ MarkdownItContainer, 'demo', { validate: params => params.trim().match(/^demo\s*(.*)$/), render: function (tokens, idx) { if (tokens[idx].nesting === 1) { return `
`; } return '
\n'; } } ], [require('markdown-it-container'), 'tip'], [require('markdown-it-container'), 'warning'], [ MarkdownItCheckBox, { disabled: true } ], [MarkdownItDec] ] }; module.exports = { mode: 'development', entry: { main: path.resolve(__dirname, '../src/main.js') }, output: { filename: 'js/[name].[hash:8].js', path: path.resolve(__dirname, 'dist'), chunkFilename: 'js/[name].[hash:8].js', publicPath: process.env.NODE_ENV === 'production' ? 'http://cdn.jskou.com/' : '/' }, devServer: { hot: true, port: 3000, contentBase: './dist' }, resolve: { alias: { vue$: 'vue/dist/vue.runtime.esm.js', '@': path.resolve(__dirname, '../src') }, extensions: [ '.mjs', '.js', '.jsx', '.vue', '.json', '.wasm' ] }, module: { rules: [ { test: /\.md$/, use: [ { loader: 'vue-loader', options: { compilerOptions: { preserveWhitespace: false } } }, { loader: 'vue-markdown-loader/lib/markdown-compiler', options: vueMarkdown } ] }, { test: /\.vue$/, use: [ { loader: 'cache-loader' }, { loader: 'thread-loader' }, { loader: 'vue-loader', options: { compilerOptions: { preserveWhitespace: false } } } ] }, { test: /\.(js|jsx)$/, exclude: /node_modules/, use: [ { loader: 'babel-loader' } ] }, { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader' } ] }, { test: /\.(jpe?g|png|gif|svg)$/i, use: [ { loader: 'url-loader', options: { limit: 4096, fallback: { loader: 'file-loader', options: { name: 'img/[name].[hash:8].[ext]' } } } } ] }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i, use: [ { loader: 'url-loader', options: { limit: 4096, fallback: { loader: 'file-loader', options: { name: 'fonts/[name].[hash:8].[ext]' } } } } ] } ] }, plugins: [ new VueLoaderPlugin(), new webpack.DefinePlugin({ 'process.env': { BASE_URL: JSON.stringify('/') } }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, '../public/index.html') }), new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin() ] };