自定義博客園樣式須要一下幾部分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!能夠用它快速地構建、安裝、分享你的博客園皮膚。