自定义博客园样式须要一下几部分css
你可能不熟悉 页首 HTML 代码 ,能够在此处放入一个 loading,由于页面加载时会最早加载这部分。总之,页面定制 CSS 代码 和 博客侧边栏公告(支持 HTML 代码) (支持 JS 代码) 是最重要的两部分。html
自定义你的皮肤可使用下面这几种方式:node
经过 webpack 咱们能够实现将 css 打包到 js, 样式由 js 动态添加。使用时只须要这样:jquery
<script src="https://guangzan.gitee.io/awescnb/index.js"></script> <script>$.awesCnb({ // 给你的皮肤添加一些配置 }) </script>
若是不暴露配置直接引入一个 js 就行了,是否是很是简单?webpack
缺点git
页面不能及时渲染 css,由于 css in js,可是咱们能够加个 loading 解决。 😀web
优势npm
这样作甚至能够实现瞬间切换多套皮肤,这里有我之前作的一个例子供您查看。点击查看切换效果.json
上面那样作的缺点很明显, 须要一个 loading, 若是咱们将 css 和 js 分离,把 css 放到 页面定制 CSS 代码,js 放到 博客侧边栏公告(支持 HTML 代码) (支持 JS 代码) 就不会出现这种状况了。经过 webpack plugin MiniCssExtractPlugin
能够将皮肤代码分别打包出一个 js 文件和一个 css 文件。sass
如何写一个架子方便开发博客园皮肤呢,下面我把 webpack 配置放出来。
options.js
我把须要常常更改的配置单独抽离一个文件,这样作能节省我不少时间。
module.exports = { themeName: 'reacg', template: 'post', eslint: true, sourceMap: false, openAnalyzer: false, cssExtract: false, }
cssExtract
若是没有开启,build 会打包生成一个 dist, dist 下仅有 js 文件,如上, 这是 css in js 的方式,经过 js 动态添加 style
; 若是设为 true ,会在 dist 目录下建立一个 ext 文件夹, 下面放了你的皮肤 js 和 css 文件。
正如你所见, ext 下每个皮肤对应 js 和 css 两个文件。
webpack.base.js
不言而喻, webpack.base.js 是开发环境和生产环境依赖的公共配置。
const path = require('path') const {themeName, eslint} = require('./options') const jsLoader = [ { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], }, }, ] if (eslint) { jsLoader.push({ loader: 'eslint-loader', options: { cache: true, }, }) } module.exports = { entry: { // 多出口 index: './src/main.js', acg: './src/themes/acg/index.js', reacg: './src/themes/reacg/index.js', gshang: './src/themes/gshang/index.js', element: './src/themes/element/index.js', [themeName]: `./src/themes/${themeName}/index.js`, }, output: { filename: '[name].js', path: path.join(__dirname, '..', 'dist'), }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: jsLoader, }, ], }, resolve: { alias: { '@': path.resolve('src'), '@awescnb': path.resolve('src/awescnb'), '@tools': path.resolve('src/assets/utils/tools'), '@plugins': path.resolve('src/plugins'), '@constants': path.resolve('src/constants'), }, }, }
这里主要关注多个 entry, 方便打包多个皮肤。
webpack.dev.js
开发环境配置
const path = require('path') const webpack = require('webpack') const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base') const HtmlWebpackPlugin = require('html-webpack-plugin') const {template, themeName, sourceMap} = require('./options') module.exports = merge(baseWebpackConfig, { mode: 'development', devtool: sourceMap ? 'inline-source-map' : '', devServer: { host: 'localhost', port: 8080, contentBase: path.join(__dirname, 'dist'), open: true, hot: true, disableHostCheck: true, proxy: {}, before() {}, }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: `src/templates/${template}.html`, inject: 'body', chunks: [`${themeName}`], }), new webpack.HotModuleReplacementPlugin({}), ], module: { rules: [ { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { importLoaders: 1, }, }, 'postcss-loader', ], }, { test: /\.scss$/, use: [ 'style-loader', { loader: 'css-loader', options: { importLoaders: 2, }, }, 'postcss-loader', 'sass-loader', ], }, ], }, })
webpack.prod.js
const path = require('path') const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base') const {openAnalyzer, cssExtract} = require('./options') // const { CleanWebpackPlugin } = require('clean-webpack-plugin') const plugins = [ // new CleanWebpackPlugin() ] let output = { filename: '[name].js', path: path.join(__dirname, '..', 'dist'), } let cssLoader = [ 'style-loader', { loader: 'css-loader', options: { importLoaders: 1, }, }, 'postcss-loader', ] let scssLoader = [ 'style-loader', { loader: 'css-loader', options: { importLoaders: 2, }, }, 'postcss-loader', 'sass-loader', ] if (openAnalyzer) { const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin plugins.push( new BundleAnalyzerPlugin({ analyzerMode: 'server', analyzerHost: '127.0.0.1', analyzerPort: 8888, reportFilename: 'report.html', defaultSizes: 'parsed', openAnalyzer: true, generateStatsFile: false, statsFilename: 'stats.json', statsOptions: null, logLevel: 'info', }) ) } if (cssExtract) { output.path = path.join(__dirname, '..', 'dist/ext') const MiniCssExtractPlugin = require('mini-css-extract-plugin') plugins.push( new MiniCssExtractPlugin({ filename: '[name].css', chunkFilename: '[id].css', ignoreOrder: false, }) ) const MiniCssExtractPluginLoader = { loader: MiniCssExtractPlugin.loader, options: { publicPath: '../', hmr: process.env.NODE_ENV === 'development', }, } cssLoader[0] = MiniCssExtractPluginLoader scssLoader[0] = MiniCssExtractPluginLoader } module.exports = merge(baseWebpackConfig, { mode: 'production', output, plugins, externals: { jquery: 'window.jquery', }, module: { rules: [ { test: /\.css$/, use: cssLoader, }, { test: /\.scss$/, use: scssLoader, }, ], }, })
经过简单的配置就能够实现任何你想要的结果。webpack 愈来愈火不是没有缘由的啊,快速上手, 生态丰富。若是 cli 用惯了,不如本身尝试打造本身的工做流。若是你没有时间造这个轮子,我已经将他封装好了, 分享给你们。 free to use!能够用它快速地构建、安装、分享你的博客园皮肤。