我想使用这个样板https://github.com/wp-strap/wordpress-plugin-boilerplate来创建Wordpress插件。
问题是
yarn prod
导致空输出(公共文件夹中的css文件为空)。
Yarn dev
工作正常。
以下是我的配置文件:
package.json
{
"name": "wordpress-webpack-workflow",
"version": "1.1.4",
"author": "WP-Strap",
"license": "MIT",
"homepage": "https://github.com/wp-strap/wordpress-webpack-workflow",
"description": "Modern WebPack workflow for WordPress front-end development and testing (plugins & themes) with handy tools included.\n",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/wp-strap/wordpress-webpack-workflow.git"
},
"bugs": {
"url": "https://github.com/wp-strap/wordpress-webpack-workflow/issues"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"prod": "webpack --env NODE_ENV=production --env production",
"prod:watch": "webpack --env NODE_ENV=production --env production --watch",
"dev": "webpack --env NODE_ENV=development",
"dev:watch": "webpack --env NODE_ENV=development --watch",
"eslint": "eslint assets/src/js/**/*.js",
"eslint:fix": "eslint assets/src/js/**/*.js --fix",
"stylelint": "stylelint assets/src/**/**/*.{css,scss,pcss}",
"stylelint:fix": "stylelint assets/src/**/**/*.{css,scss,pcss} --fix",
"prettier": "prettier assets/src/js/**/*.js",
"prettier:fix": "prettier --write assets/src/js/**/*.js",
"translate": "wp-pot --src '**/**/**/*.php' --dest-file 'languages/report-error.pot' --package 'report-error' --domain 'report-error' --last-translator 'WP SCRIPT LAB <[email protected]>' --team 'WP SCRIPT LAB <[email protected]>' --bug-report 'wpscriptlab.com'"
},
"babel": {
"extends": "./webpack/babel.config.js"
},
"eslintConfig": {
"extends": [
"./webpack/.eslintrc.js"
]
},
"prettier": "./webpack/.prettierrc.js",
"stylelint": {
"ignoreFiles": [
"./assets/public/css/**/*.css",
"./vendor/**/**/*.css",
"./node_modules/**/**/*.css",
"./tests/**/**/*.css"
],
"extends": [
"./webpack/.stylelintrc.js"
]
},
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/eslint-parser": "^7.12.1",
"@babel/preset-env": "^7.12.11",
"@wordpress/eslint-plugin": "^7.4.0",
"autoprefixer": "^10.2.1",
"babel-loader": "^8.2.2",
"browser-sync": "^2.26.13",
"browser-sync-webpack-plugin": "^2.3.0",
"copy-webpack-plugin": "^7.0.0",
"css-loader": "^5.0.1",
"eslint": "^7.17.0",
"eslint-webpack-plugin": "^2.4.1",
"eslint-plugin-prettier": "^3.3.1",
"glob-all": "^3.2.1",
"image-minimizer-webpack-plugin": "^2.2.0",
"imagemin-gifsicle": "^7.0.0",
"imagemin-jpegtran": "^7.0.0",
"imagemin-optipng": "^8.0.0",
"imagemin-svgo": "^8.0.0",
"mini-css-extract-plugin": "^1.3.3",
"node-sass-magic-importer": "^5.3.2",
"postcss": "^8.2.4",
"postcss-advanced-variables": "^3.0.1",
"postcss-import": "^14.0.0",
"postcss-import-ext-glob": "^2.0.0",
"postcss-loader": "^4.1.0",
"postcss-nested": "^5.0.3",
"postcss-nested-ancestors": "^2.0.0",
"prettier": "^2.2.1",
"purgecss-webpack-plugin": "^3.1.3",
"sass": "^1.32.2",
"sass-loader": "^10.1.0",
"stylelint": "^13.8.0",
"stylelint-scss": "^3.18.0",
"stylelint-webpack-plugin": "^2.1.1",
"webpack": "^5.12.3",
"webpack-cli": "^4.3.1",
"webpackbar": "^5.0.0-3",
"wp-pot-cli": "^1.5.0"
},
"keywords": [
"wordpress",
"workflow",
"webpack",
"theme",
"plugin",
"WebPack",
"BrowserSync",
"PostCSS",
"Autoprefixer",
"PurgeCSS",
"BabelJS",
"Eslint",
"Stylelint",
"SCSS",
"WP-Pot"
]
}
composer.json
{
"name": "wpstrap/wordpress-plugin-boilerplate",
"description": "Wordpress Plugin Boilerplate",
"version": "0.3.1",
"minimum-stability": "stable",
"prefer-stable": true,
"type": "wordpress-plugin",
"license": "MIT",
"homepage": "https://wp-strap.com",
"autoload": {
"psr-4": {
"ReportError\\": "src/"
}
},
"scripts": {
"phpcs": "./vendor/bin/phpcs"
},
"require": {
"php": ">=7.1",
"micropackage/requirements": "^1.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.1",
"wp-coding-standards/wpcs": "*",
"automattic/phpcs-neutron-ruleset": "^3.3",
"phpcompatibility/phpcompatibility-wp": "^2.1"
},
"keywords": [
"wordpress",
"plugin",
"boilerplate",
"framework"
],
"authors": [
{
"name": "WP-Strap",
"email": "[email protected]",
"homepage": "https://wp-strap.com"
}
],
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}
webpack.config.js
/**
* This is a main entrypoint for Webpack config.
*
* @since 1.0.0
*/
const path = require( 'path' );
// Paths to find our files and provide BrowserSync functionality.
const projectPaths = {
projectDir: __dirname, // Current project directory absolute path.
projectJsPath: path.resolve( __dirname, 'assets/src/js' ),
projectScssPath: path.resolve( __dirname, 'assets/src/scss' ),
projectImagesPath: path.resolve( __dirname, 'assets/src/images' ),
projectOutput: path.resolve( __dirname, 'assets/public' ),
projectWebpack: path.resolve( __dirname, 'webpack' ),
};
// Files to bundle
const projectFiles = {
// BrowserSync settings
browserSync: {
enable: true, // enable or disable browserSync
host: 'localhost',
port: 3000,
mode: 'proxy', // proxy | server
server: { baseDir: [ 'public' ] }, // can be ignored if using proxy
proxy: 'report-error.local',
// BrowserSync will automatically watch for changes to any files connected to our entry,
// including both JS and Sass files. We can use this property to tell BrowserSync to watch
// for other types of files, in this case PHP files, in our project.
files: '**/**/**.php',
reload: true, // Set false to prevent BrowserSync from reloading and let Webpack Dev Server take care of this
// browse to http://localhost:3000/ during development,
},
// JS configurations for development and production
projectJs: {
eslint: true, // enable or disable eslint | this is only enabled in development env.
filename: 'js/[name].js',
entry: {
frontend: projectPaths.projectJsPath + '/frontend.js',
backend: projectPaths.projectJsPath + '/backend.js',
},
rules: {
test: /\.m?js$/,
}
},
// CSS configurations for development and production
projectCss: {
postCss: projectPaths.projectWebpack + '/postcss.config.js',
stylelint: true, // enable or disable stylelint | this is only enabled in development env.
filename: 'css/[name].css',
use: 'sass', // sass || postcss
// ^ If you want to change from Sass to PostCSS or PostCSS to Sass then you need to change the
// styling files which are being imported in "assets/src/js/frontend.js" and "assets/src/js/backend.js".
// So change "import '../sass/backend.scss'" to "import '../postcss/backend.pcss'" for example
rules: {
sass: {
test: /\.s[ac]ss$/i
},
postcss: {
test: /\.pcss$/i
}
},
purgeCss: { // PurgeCSS is only being activated in production environment
paths: [ // Specify content that should be analyzed by PurgeCSS
__dirname + '/assets/src/js/**/*',
__dirname + '/templates/**/**/*',
__dirname + '/template-parts/**/**/*',
__dirname + '/blocks/**/**/*',
__dirname + '/*.php',
]
}
},
// Source Maps configurations
projectSourceMaps: {
// Sourcemaps are nice for debugging but takes lots of time to compile,
// so we disable this by default and can be enabled when necessary
enable: true,
env: 'dev-prod', // dev | dev-prod | prod
// ^ Enabled only for development on default, use "prod" to enable only for production
// or "dev-prod" to enable it for both production and development
devtool: 'source-map' // type of sourcemap, see more info here: https://webpack.js.org/configuration/devtool/
// ^ If "source-map" is too slow, then use "cheap-source-map" which struck a good balance between build performance and debuggability.
},
// Images configurations for development and production
projectImages: {
rules: {
test: /\.(jpe?g|png|gif|svg)$/i,
},
// Optimization settings
minimizerOptions: {
// Lossless optimization with custom option
// Feel free to experiment with options for better result for you
// More info here: https://webpack.js.org/plugins/image-minimizer-webpack-plugin/
plugins: [
[ 'gifsicle', { interlaced: true } ],
[ 'jpegtran', { progressive: true } ],
[ 'optipng', { optimizationLevel: 5 } ],
[ 'svgo', {
plugins: [
{ removeViewBox: false, },
],
}, ],
],
}
}
}
// Merging the projectFiles & projectPaths objects
const projectOptions = {
...projectPaths, ...projectFiles,
projectConfig: {
// add extra options here
}
}
// Get the development or production setup based
// on the script from package.json
module.exports = env => {
if ( env.NODE_ENV === 'production' ) {
return require( './webpack/config.production' )( projectOptions );
} else {
return require( './webpack/config.development' )( projectOptions );
}
};
config.base.js
/**
* This holds the configuration that is being used for both development and production.
* This is being imported and extended in the config.development.js and config.production.js files
*
* @since 1.1.0
*/
const magicImporter = require( 'node-sass-magic-importer' ); // Add magic import functionalities to SASS
const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' ); // Extracts the CSS files into public/css
const BrowserSyncPlugin = require( 'browser-sync-webpack-plugin' ) // Synchronising URLs, interactions and code changes across devices
const WebpackBar = require( 'webpackbar' ); // Display elegant progress bar while building or watch
const ImageMinimizerPlugin = require( 'image-minimizer-webpack-plugin' ); // To optimize (compress) all images using
const CopyPlugin = require( "copy-webpack-plugin" ); // For WordPress we need to copy images from src to public to optimize them
module.exports = ( projectOptions ) => {
/**
* CSS Rules
*/
const cssRules = {
test: projectOptions.projectCss.use === 'sass' ? projectOptions.projectCss.rules.sass.test : projectOptions.projectCss.rules.postcss.test,
exclude: /(node_modules|bower_components|vendor)/,
use: [
MiniCssExtractPlugin.loader, // Creates `style` nodes from JS strings
"css-loader", // Translates CSS into CommonJS
{ // loads the PostCSS loader
loader: "postcss-loader",
options: require( projectOptions.projectCss.postCss )( projectOptions )
}
],
};
if ( projectOptions.projectCss.use === 'sass' ) { // if chosen Sass then we're going to add the Sass loader
cssRules.use.push( { // Compiles Sass to CSS
loader: 'sass-loader',
options: {
sassOptions: { importer: magicImporter() } // add magic import functionalities to sass
}
} );
}
/**
* JavaScript rules
*/
const jsRules = {
test: projectOptions.projectJs.rules.test,
include: projectOptions.projectJsPath,
exclude: /(node_modules|bower_components|vendor)/,
use: 'babel-loader' // Configurations in "webpack/babel.config.js"
};
/**
* Images rules
*/
const imageRules = {
test: projectOptions.projectImages.rules.test,
use: [
{
loader: 'file-loader',// Or `url-loader` or your other loader
},
],
}
/**
* Optimization rules
*/
const optimizations = {};
/**
* Plugins
*/
const plugins = [
new WebpackBar( // Adds loading bar during builds
// Uncomment this to enable profiler https://github.com/nuxt-contrib/webpackbar#options
// { reporters: [ 'profile' ], profile: true }
),
new MiniCssExtractPlugin( { // Extracts CSS files
filename: projectOptions.projectCss.filename
} ),
new CopyPlugin( { // Copies images from src to public
patterns: [ { from: projectOptions.projectImagesPath, to: projectOptions.projectOutput + '/images' }, ],
} ),
new ImageMinimizerPlugin( { // Optimizes images
minimizerOptions: projectOptions.projectImages.minimizerOptions,
} ),
];
// Add browserSync to plugins if enabled
if ( projectOptions.browserSync.enable === true ) {
const browserSyncOptions = {
files: projectOptions.browserSync.files,
host: projectOptions.browserSync.host,
port: projectOptions.browserSync.port,
}
if ( projectOptions.browserSync.mode === 'server' ) {
Object.assign( browserSyncOptions, { server: projectOptions.browserSync.server } )
} else {
Object.assign( browserSyncOptions, { proxy: projectOptions.browserSync.proxy } )
}
plugins.push( new BrowserSyncPlugin( browserSyncOptions, { reload: projectOptions.browserSync.reload } ) )
}
return {
cssRules: cssRules, jsRules: jsRules, imageRules: imageRules, optimizations: optimizations, plugins: plugins
}
}
config.生产.js
/**
* Webpack configurations for the production environment
* based on the script from package.json
* Run with: "npm run prod" or or "npm run prod:watch"
*
* @since 1.0.0
*/
const glob = require( 'glob-all' );
const PurgecssPlugin = require( 'purgecss-webpack-plugin' ) // A tool to remove unused CSS
module.exports = ( projectOptions ) => {
process.env.NODE_ENV = 'production'; // Set environment level to 'production'
/**
* The base skeleton
*/
const Base = require( './config.base' )( projectOptions );
/**
* CSS rules
*/
const cssRules = {
...Base.cssRules, ...{
// add CSS rules for production here
}
};
/**
* JS rules
*/
const jsRules = {
...Base.jsRules, ...{
// add JS rules for production here
}
};
/**
* Image rules
*/
const imageRules = {
...Base.imageRules, ...{
// add image rules for production here
}
}
/**
* Optimizations rules
*/
const optimizations = {
...Base.optimizations, ...{
splitChunks: {
cacheGroups: {
styles: { // Configured for PurgeCSS
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true
}
}
}
// add optimizations rules for production here
}
}
/**
* Plugins
*/
const plugins = [
...Base.plugins, ...[
new PurgecssPlugin( { // Scans files and removes unused CSS
paths: glob.sync( projectOptions.projectCss.purgeCss.paths, { nodir: true } ),
} ),
// add plugins for production here
]
]
/**
* Add sourcemap for production if enabled
*/
const sourceMap = { devtool: false };
if ( projectOptions.projectSourceMaps.enable === true && (
projectOptions.projectSourceMaps.env === 'prod' || projectOptions.projectSourceMaps.env === 'dev-prod'
) ) {
sourceMap.devtool = projectOptions.projectSourceMaps.devtool;
}
/**
* The configuration that's being returned to Webpack
*/
return {
mode: 'production',
entry: projectOptions.projectJs.entry, // Define the starting point of the application.
output: {
path: projectOptions.projectOutput,
filename: projectOptions.projectJs.filename
},
devtool: sourceMap.devtool,
optimization: optimizations,
module: { rules: [ cssRules, jsRules, imageRules ], },
plugins: plugins,
}
}